perf c2c report: Decode c2c_stats for hist entries

Decoding and storing c2c_stats for each hist entry.  Changing related
function to work with c2c_* objects.

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-19-git-send-email-jolsa@kernel.org
[ Add '.nr_entries = 0' to the c2c_stats initialization to fix the build on older distros ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index df413b5..43f18aa3 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -14,10 +14,12 @@
 struct c2c_hists {
 	struct hists		hists;
 	struct perf_hpp_list	list;
+	struct c2c_stats	stats;
 };
 
 struct c2c_hist_entry {
 	struct c2c_hists	*hists;
+	struct c2c_stats	 stats;
 	/*
 	 * must be at the end,
 	 * because of its callchain dynamic entry
@@ -64,9 +66,9 @@
 static int c2c_hists__init(struct c2c_hists *hists,
 			   const char *sort);
 
-static struct hists*
-he__get_hists(struct hist_entry *he,
-	      const char *sort)
+static struct c2c_hists*
+he__get_c2c_hists(struct hist_entry *he,
+		  const char *sort)
 {
 	struct c2c_hist_entry *c2c_he;
 	struct c2c_hists *hists;
@@ -74,7 +76,7 @@
 
 	c2c_he = container_of(he, struct c2c_hist_entry, he);
 	if (c2c_he->hists)
-		return &c2c_he->hists->hists;
+		return c2c_he->hists;
 
 	hists = c2c_he->hists = zalloc(sizeof(*hists));
 	if (!hists)
@@ -86,7 +88,7 @@
 		return NULL;
 	}
 
-	return &hists->hists;
+	return hists;
 }
 
 static int process_sample_event(struct perf_tool *tool __maybe_unused,
@@ -95,7 +97,9 @@
 				struct perf_evsel *evsel __maybe_unused,
 				struct machine *machine)
 {
-	struct hists *hists = &c2c.hists.hists;
+	struct c2c_hists *c2c_hists = &c2c.hists;
+	struct c2c_hist_entry *c2c_he;
+	struct c2c_stats stats = { .nr_entries = 0, };
 	struct hist_entry *he;
 	struct addr_location al;
 	struct mem_info *mi, *mi_dup;
@@ -115,13 +119,19 @@
 	if (!mi_dup)
 		goto free_mi;
 
-	he = hists__add_entry_ops(hists, &c2c_entry_ops,
+	c2c_decode_stats(&stats, mi);
+
+	he = hists__add_entry_ops(&c2c_hists->hists, &c2c_entry_ops,
 				  &al, NULL, NULL, mi,
 				  sample, true);
 	if (he == NULL)
 		goto free_mi_dup;
 
-	hists__inc_nr_samples(hists, he->filtered);
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+	c2c_add_stats(&c2c_he->stats, &stats);
+	c2c_add_stats(&c2c_hists->stats, &stats);
+
+	hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
 	ret = hist_entry__append_callchain(he, sample);
 
 	if (!ret) {
@@ -131,17 +141,21 @@
 		if (!mi_dup)
 			goto free_mi;
 
-		hists = he__get_hists(he, "offset");
-		if (!hists)
+		c2c_hists = he__get_c2c_hists(he, "offset");
+		if (!c2c_hists)
 			goto free_mi_dup;
 
-		he = hists__add_entry_ops(hists, &c2c_entry_ops,
+		he = hists__add_entry_ops(&c2c_hists->hists, &c2c_entry_ops,
 					  &al, NULL, NULL, mi,
 					  sample, true);
 		if (he == NULL)
 			goto free_mi_dup;
 
-		hists__inc_nr_samples(hists, he->filtered);
+		c2c_he = container_of(he, struct c2c_hist_entry, he);
+		c2c_add_stats(&c2c_he->stats, &stats);
+		c2c_add_stats(&c2c_hists->stats, &stats);
+
+		hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
 		ret = hist_entry__append_callchain(he, sample);
 	}