All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] perf tools: Assorted fixes
@ 2018-03-07 15:50 Jiri Olsa
  2018-03-07 15:50 ` [PATCH 01/19] perf report: Fix the output for stdio events list Jiri Olsa
                   ` (18 more replies)
  0 siblings, 19 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

hi,
sending assorted general fixes that queued
up in my other branches.

Also available in here:
  https://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/fixes

thanks,
jirka


---
Jiri Olsa (19):
      perf report: Fix the output for stdio events list
      perf report: Display perf.data header info
      perf record: Move machine variable down the function
      perf record: Remove progname from struct record
      perf tools: Add refcnt into struct mem_info
      perf c2c: Use mem_info refcnt logic
      perf tools: Add MEM_TOPOLOGY feature to perf data file
      perf tools: Add mem2node object
      perf tests: Add mem2node object test
      perf c2c record: Record physical addresses in samples
      perf c2c report: Make calc_width work with struct c2c_hist_entry
      perf c2c report: Call calc_width only for displayed entries
      perf c2c report: Display node for cacheline address
      perf c2c report: Add span header over cacheline data
      perf c2c report: Add cacheline address count column
      perf tools: Update tags with .cpp files
      perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA
      perf build: Add llvm/clang make targets to FILES
      perf build: Force llvm/clang test compile output to .make.output

 tools/build/Makefile.feature          |   6 ++-
 tools/build/feature/Makefile          |  14 ++++--
 tools/include/linux/bitmap.h          |   2 +-
 tools/perf/Documentation/perf-c2c.txt |   2 +-
 tools/perf/Makefile.perf              |   6 +--
 tools/perf/builtin-c2c.c              | 249 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
 tools/perf/builtin-record.c           |   7 +--
 tools/perf/builtin-report.c           |  17 +++++--
 tools/perf/tests/Build                |   1 +
 tools/perf/tests/builtin-test.c       |   4 ++
 tools/perf/tests/mem2node.c           |  73 +++++++++++++++++++++++++++
 tools/perf/tests/tests.h              |   1 +
 tools/perf/ui/browsers/hists.c        |   5 +-
 tools/perf/util/Build                 |   1 +
 tools/perf/util/env.h                 |   9 ++++
 tools/perf/util/evsel.c               |  20 ++++++--
 tools/perf/util/evsel.h               |   1 +
 tools/perf/util/header.c              | 312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 tools/perf/util/header.h              |   1 +
 tools/perf/util/hist.c                |   4 +-
 tools/perf/util/machine.c             |   2 +-
 tools/perf/util/mem2node.c            | 129 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/mem2node.h            |  19 +++++++
 tools/perf/util/symbol.c              |  22 ++++++++
 tools/perf/util/symbol.h              |  19 +++++--
 25 files changed, 864 insertions(+), 62 deletions(-)
 create mode 100644 tools/perf/tests/mem2node.c
 create mode 100644 tools/perf/util/mem2node.c
 create mode 100644 tools/perf/util/mem2node.h

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

* [PATCH 01/19] perf report: Fix the output for stdio events list
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:51   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 02/19] perf report: Display perf.data header info Jiri Olsa
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Changing the output header for reporting forced groups
via --groups option on non grouped events, like:

  $ perf record -e 'cycles,instructions'
  $ perf report --stdio --group

Before:
  # Samples: 24  of event 'anon group { cycles:u, instructions:u }'

After:
  # Samples: 24  of events 'cycles:u, instructions:u'

Link: http://lkml.kernel.org/n/tip-1uizixi38t1v9cj2sgtmkj8o@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-report.c    | 17 ++++++++++++++---
 tools/perf/ui/browsers/hists.c |  5 +++--
 tools/perf/util/evsel.c        | 20 ++++++++++++++++----
 tools/perf/util/evsel.h        |  1 +
 4 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1eedb1815c4c..c3603d4c0c57 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -400,8 +400,10 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
 
 	nr_samples = convert_unit(nr_samples, &unit);
 	ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
-	if (evname != NULL)
-		ret += fprintf(fp, " of event '%s'", evname);
+	if (evname != NULL) {
+		ret += fprintf(fp, " of event%s '%s'",
+			       evsel->nr_members > 1 ? "s" : "", evname);
+	}
 
 	if (rep->time_str)
 		ret += fprintf(fp, " (time slices: %s)", rep->time_str);
@@ -1175,8 +1177,17 @@ int cmd_report(int argc, const char **argv)
 	has_br_stack = perf_header__has_feat(&session->header,
 					     HEADER_BRANCH_STACK);
 
-	if (group_set && !session->evlist->nr_groups)
+	/*
+	 * Events in data file are not collect in groups, but we still want
+	 * the group display. Set the artificial group and set the leader's
+	 * forced_leader flag to notify the display code.
+	 */
+	if (group_set && !session->evlist->nr_groups) {
+		struct perf_evsel *leader = perf_evlist__first(session->evlist);
+
 		perf_evlist__set_leader(session->evlist);
+		leader->forced_leader = true;
+	}
 
 	if (itrace_synth_opts.last_branch)
 		has_br_stack = true;
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index de2bde232cb3..8b4e82548f8e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -2261,8 +2261,9 @@ static int perf_evsel_browser_title(struct hist_browser *browser,
 
 	nr_samples = convert_unit(nr_samples, &unit);
 	printed = scnprintf(bf, size,
-			   "Samples: %lu%c of event '%s',%s%sEvent count (approx.): %" PRIu64,
-			   nr_samples, unit, ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
+			   "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
+			   nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
+			   ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
 
 
 	if (hists->uid_filter_str)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f1f883bb41a8..8948a8c1c187 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -621,22 +621,34 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel)
 	return evsel->group_name ?: "anon group";
 }
 
+/*
+ * Returns the group details for the specified leader,
+ * with following rules.
+ *
+ *  For record -e '{cycles,instructions}'
+ *    'anon group { cycles:u, instructions:u }'
+ *
+ *  For record -e 'cycles,instructions' and report --group
+ *    'cycles:u, instructions:u'
+ */
 int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
 {
-	int ret;
+	int ret = 0;
 	struct perf_evsel *pos;
 	const char *group_name = perf_evsel__group_name(evsel);
 
-	ret = scnprintf(buf, size, "%s", group_name);
+	if (!evsel->forced_leader)
+		ret = scnprintf(buf, size, "%s { ", group_name);
 
-	ret += scnprintf(buf + ret, size - ret, " { %s",
+	ret += scnprintf(buf + ret, size - ret, "%s",
 			 perf_evsel__name(evsel));
 
 	for_each_group_member(pos, evsel)
 		ret += scnprintf(buf + ret, size - ret, ", %s",
 				 perf_evsel__name(pos));
 
-	ret += scnprintf(buf + ret, size - ret, " }");
+	if (!evsel->forced_leader)
+		ret += scnprintf(buf + ret, size - ret, " }");
 
 	return ret;
 }
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 92ba001b627f..bb17afc429d9 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -125,6 +125,7 @@ struct perf_evsel {
 	bool			per_pkg;
 	bool			precise_max;
 	bool			ignore_missing_thread;
+	bool			forced_leader;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;
-- 
2.13.6

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

* [PATCH 02/19] perf report: Display perf.data header info
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
  2018-03-07 15:50 ` [PATCH 01/19] perf report: Fix the output for stdio events list Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:52   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 03/19] perf record: Move machine variable down the function Jiri Olsa
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Display more header info from perf.data file,
following values:

  $ perf report -i perf.data --header-only
  ...
  # header version : 1
  # data offset    : 424
  # data size      : 3364280
  # feat offset    : 3364704

It's handy for debuging.

Link: http://lkml.kernel.org/n/tip-bdfzdy1xv8ocs6ukk31sgxsw@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/header.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a326e0d8b5b6..e0c3cad0fd8d 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2318,7 +2318,12 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
 	if (ret == -1)
 		return -1;
 
-	fprintf(fp, "# captured on: %s", ctime(&st.st_ctime));
+	fprintf(fp, "# captured on    : %s", ctime(&st.st_ctime));
+
+	fprintf(fp, "# header version : %u\n", header->version);
+	fprintf(fp, "# data offset    : %" PRIu64 "\n", header->data_offset);
+	fprintf(fp, "# data size      : %" PRIu64 "\n", header->data_size);
+	fprintf(fp, "# feat offset    : %" PRIu64 "\n", header->feat_offset);
 
 	perf_header__process_sections(header, fd, &hd,
 				      perf_file_section__fprintf_info);
-- 
2.13.6

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

* [PATCH 03/19] perf record: Move machine variable down the function
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
  2018-03-07 15:50 ` [PATCH 01/19] perf report: Fix the output for stdio events list Jiri Olsa
  2018-03-07 15:50 ` [PATCH 02/19] perf report: Display perf.data header info Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:52   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 04/19] perf record: Remove progname from struct record Jiri Olsa
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

It's used far more down to be declared on the top of the __cmd_record.

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

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 14d82f0fe5cc..b2ebd9b3feba 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -854,7 +854,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	int status = 0;
 	unsigned long waking = 0;
 	const bool forks = argc > 0;
-	struct machine *machine;
 	struct perf_tool *tool = &rec->tool;
 	struct record_opts *opts = &rec->opts;
 	struct perf_data *data = &rec->data;
@@ -959,8 +958,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 		goto out_child;
 	}
 
-	machine = &session->machines.host;
-
 	err = record__synthesize(rec, false);
 	if (err < 0)
 		goto out_child;
@@ -988,6 +985,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	 * Let the child rip
 	 */
 	if (forks) {
+		struct machine *machine = &session->machines.host;
 		union perf_event *event;
 		pid_t tgid;
 
-- 
2.13.6

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

* [PATCH 04/19] perf record: Remove progname from struct record
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (2 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 03/19] perf record: Move machine variable down the function Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:53   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 05/19] perf tools: Add refcnt into struct mem_info Jiri Olsa
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

It's no longer used.

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

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index b2ebd9b3feba..68caf54aa191 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -71,7 +71,6 @@ struct record {
 	struct auxtrace_record	*itr;
 	struct perf_evlist	*evlist;
 	struct perf_session	*session;
-	const char		*progname;
 	int			realtime_prio;
 	bool			no_buildid;
 	bool			no_buildid_set;
@@ -861,8 +860,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	bool disabled = false, draining = false;
 	int fd;
 
-	rec->progname = argv[0];
-
 	atexit(record__sig_exit);
 	signal(SIGCHLD, sig_handler);
 	signal(SIGINT, sig_handler);
-- 
2.13.6

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

* [PATCH 05/19] perf tools: Add refcnt into struct mem_info
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (3 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 04/19] perf record: Remove progname from struct record Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 18:56   ` Arnaldo Carvalho de Melo
  2018-03-09  8:53   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 06/19] perf c2c: Use mem_info refcnt logic Jiri Olsa
                   ` (13 subsequent siblings)
  18 siblings, 2 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

It's passed along several hists entries in --hierarchy mode,
so it's better we keep track of it.

The current fail I see is that it gets removed in hierarchy
--mem-mode mode, where it's shared in the different hierarchies,
but removed from the template hist entry, so the report crashes.

Link: http://lkml.kernel.org/n/tip-vwr82ygpfv4kisaxfyopaef6@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/hist.c    |  4 ++--
 tools/perf/util/machine.c |  2 +-
 tools/perf/util/symbol.c  | 22 ++++++++++++++++++++++
 tools/perf/util/symbol.h  | 19 ++++++++++++++++---
 4 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 44a8456cea10..7d968892ee39 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -536,7 +536,7 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
 			 * This mem info was allocated from sample__resolve_mem
 			 * and will not be used anymore.
 			 */
-			zfree(&entry->mem_info);
+			mem_info__zput(entry->mem_info);
 
 			/* If the map of an existing hist_entry has
 			 * become out-of-date due to an exec() or
@@ -1139,7 +1139,7 @@ void hist_entry__delete(struct hist_entry *he)
 	if (he->mem_info) {
 		map__zput(he->mem_info->iaddr.map);
 		map__zput(he->mem_info->daddr.map);
-		zfree(&he->mem_info);
+		mem_info__zput(he->mem_info);
 	}
 
 	zfree(&he->stat_acc);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 12b7427444a3..d46c98d6dedd 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1697,7 +1697,7 @@ static void ip__resolve_data(struct thread *thread,
 struct mem_info *sample__resolve_mem(struct perf_sample *sample,
 				     struct addr_location *al)
 {
-	struct mem_info *mi = zalloc(sizeof(*mi));
+	struct mem_info *mi = mem_info__aloc();
 
 	if (!mi)
 		return NULL;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index a1a312d99f30..117cd25cd21a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2221,3 +2221,25 @@ int symbol__config_symfs(const struct option *opt __maybe_unused,
 	free(bf);
 	return 0;
 }
+
+struct mem_info *mem_info__get(struct mem_info *mi)
+{
+	if (mi)
+		refcount_inc(&mi->refcnt);
+	return mi;
+}
+
+void mem_info__put(struct mem_info *mi)
+{
+	if (mi && refcount_dec_and_test(&mi->refcnt))
+		free(mi);
+}
+
+struct mem_info *mem_info__aloc(void)
+{
+	struct mem_info *mi = zalloc(sizeof(*mi));
+
+	if (mi)
+		refcount_set(&mi->refcnt, 1);
+	return mi;
+}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 0563f33c1eb3..7e3ac7f35d63 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -200,9 +200,10 @@ struct branch_info {
 };
 
 struct mem_info {
-	struct addr_map_symbol iaddr;
-	struct addr_map_symbol daddr;
-	union perf_mem_data_src data_src;
+	struct addr_map_symbol	iaddr;
+	struct addr_map_symbol	daddr;
+	union perf_mem_data_src	data_src;
+	refcount_t		refcnt;
 };
 
 struct addr_location {
@@ -389,4 +390,16 @@ int sdt_notes__get_count(struct list_head *start);
 #define SDT_NOTE_NAME "stapsdt"
 #define NR_ADDR 3
 
+struct mem_info *mem_info__aloc(void);
+struct mem_info *mem_info__get(struct mem_info *mi);
+void   mem_info__put(struct mem_info *mi);
+
+static inline void __mem_info__zput(struct mem_info **mi)
+{
+	mem_info__put(*mi);
+	*mi = NULL;
+}
+
+#define mem_info__zput(mi) __mem_info__zput(&mi)
+
 #endif /* __PERF_SYMBOL */
-- 
2.13.6

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

* [PATCH 06/19] perf c2c: Use mem_info refcnt logic
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (4 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 05/19] perf tools: Add refcnt into struct mem_info Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:54   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file Jiri Olsa
                   ` (12 subsequent siblings)
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Switch to refcnt logic instead of duplicating
mem_info objects. No functional change, just
saving some memory.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 539c3d460158..98d243fa0c06 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -237,9 +237,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 	if (mi == NULL)
 		return -ENOMEM;
 
-	mi_dup = memdup(mi, sizeof(*mi));
-	if (!mi_dup)
-		goto free_mi;
+	/*
+	 * The mi object is released in hists__add_entry_ops,
+	 * if it gets sorted out into existing data, so we need
+	 * to take the copy now.
+	 */
+	mi_dup = mem_info__get(mi);
 
 	c2c_decode_stats(&stats, mi);
 
@@ -247,7 +250,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 				  &al, NULL, NULL, mi,
 				  sample, true);
 	if (he == NULL)
-		goto free_mi_dup;
+		goto free_mi;
 
 	c2c_he = container_of(he, struct c2c_hist_entry, he);
 	c2c_add_stats(&c2c_he->stats, &stats);
@@ -272,19 +275,15 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 
 		mi = mi_dup;
 
-		mi_dup = memdup(mi, sizeof(*mi));
-		if (!mi_dup)
-			goto free_mi;
-
 		c2c_hists = he__get_c2c_hists(he, c2c.cl_sort, 2);
 		if (!c2c_hists)
-			goto free_mi_dup;
+			goto free_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;
+			goto free_mi;
 
 		c2c_he = container_of(he, struct c2c_hist_entry, he);
 		c2c_add_stats(&c2c_he->stats, &stats);
@@ -303,10 +302,9 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 	addr_location__put(&al);
 	return ret;
 
-free_mi_dup:
-	free(mi_dup);
 free_mi:
-	free(mi);
+	mem_info__put(mi_dup);
+	mem_info__put(mi);
 	ret = -ENOMEM;
 	goto out;
 }
-- 
2.13.6

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

* [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (5 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 06/19] perf c2c: Use mem_info refcnt logic Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 19:28   ` Arnaldo Carvalho de Melo
  2018-03-09  8:54   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 08/19] perf tools: Add mem2node object Jiri Olsa
                   ` (11 subsequent siblings)
  18 siblings, 2 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Adding MEM_TOPOLOGY feature to perf data file,
that will carry physical memory map and its
node assignments.

The format of data in MEM_TOPOLOGY is as follows:

  0 - version          | for future changes
  8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
 16 - count            | number of nodes

 For each node we store map of physical indexes for
 each node:

 32 - node id          | node index
 40 - size             | size of bitmap
 48 - bitmap           | bitmap of memory indexes that belongs to node
                       | /sys/devices/system/node/node<NODE>/memory<INDEX>

The MEM_TOPOLOGY could be displayed with following
report command:

  $ perf report --header-only -I
  ...
  # memory nodes (nr 1, block size 0x8000000):
  #    0 [7G]: 0-23,32-69

Link: http://lkml.kernel.org/n/tip-qq7sohu774wxq154n3my037z@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/include/linux/bitmap.h |   2 +-
 tools/perf/util/env.h        |   9 ++
 tools/perf/util/header.c     | 305 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.h     |   1 +
 4 files changed, 316 insertions(+), 1 deletion(-)

diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index ca160270fdfa..63440cc8d618 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -98,7 +98,7 @@ static inline int test_and_set_bit(int nr, unsigned long *addr)
 
 /**
  * bitmap_alloc - Allocate bitmap
- * @nr: Bit to set
+ * @nbits: Number of bits
  */
 static inline unsigned long *bitmap_alloc(int nbits)
 {
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index bf970f57dce0..c4ef2e523367 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -27,6 +27,12 @@ struct numa_node {
 	struct cpu_map	*map;
 };
 
+struct memory_node {
+	u64		 node;
+	u64		 size;
+	unsigned long	*set;
+};
+
 struct perf_env {
 	char			*hostname;
 	char			*os_release;
@@ -43,6 +49,7 @@ struct perf_env {
 	int			nr_sibling_cores;
 	int			nr_sibling_threads;
 	int			nr_numa_nodes;
+	int			nr_memory_nodes;
 	int			nr_pmu_mappings;
 	int			nr_groups;
 	char			*cmdline;
@@ -54,6 +61,8 @@ struct perf_env {
 	struct cpu_cache_level	*caches;
 	int			 caches_cnt;
 	struct numa_node	*numa_nodes;
+	struct memory_node	*memory_nodes;
+	unsigned long long	 memory_bsize;
 };
 
 extern struct perf_env perf_env;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e0c3cad0fd8d..3a107e7ac135 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -17,6 +17,7 @@
 #include <sys/stat.h>
 #include <sys/utsname.h>
 #include <linux/time64.h>
+#include <dirent.h>
 
 #include "evlist.h"
 #include "evsel.h"
@@ -37,6 +38,7 @@
 #include "asm/bug.h"
 #include "tool.h"
 #include "time-utils.h"
+#include "units.h"
 
 #include "sane_ctype.h"
 
@@ -132,6 +134,25 @@ int do_write(struct feat_fd *ff, const void *buf, size_t size)
 }
 
 /* Return: 0 if succeded, -ERR if failed. */
+static int do_write_bitmap(struct feat_fd *ff, unsigned long *set, u64 size)
+{
+	u64 *p = (u64 *) set;
+	int i, ret;
+
+	ret = do_write(ff, &size, sizeof(size));
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
+		ret = do_write(ff, p + i, sizeof(*p));
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+/* Return: 0 if succeded, -ERR if failed. */
 int write_padded(struct feat_fd *ff, const void *bf,
 		 size_t count, size_t count_aligned)
 {
@@ -243,6 +264,38 @@ static char *do_read_string(struct feat_fd *ff)
 	return NULL;
 }
 
+/* Return: 0 if succeded, -ERR if failed. */
+static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize)
+{
+	unsigned long *set;
+	u64 size, *p;
+	int i, ret;
+
+	ret = do_read_u64(ff, &size);
+	if (ret)
+		return ret;
+
+	set = bitmap_alloc(size);
+	if (!set)
+		return -ENOMEM;
+
+	bitmap_zero(set, size);
+
+	p = (u64 *) set;
+
+	for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
+		ret = do_read_u64(ff, p + i);
+		if (ret < 0) {
+			free(set);
+			return ret;
+		}
+	}
+
+	*pset  = set;
+	*psize = size;
+	return 0;
+}
+
 static int write_tracing_data(struct feat_fd *ff,
 			      struct perf_evlist *evlist)
 {
@@ -1196,6 +1249,176 @@ static int write_sample_time(struct feat_fd *ff,
 			sizeof(evlist->last_sample_time));
 }
 
+
+static int memory_node__read(struct memory_node *n, unsigned long index)
+{
+	unsigned int phys, size = 0;
+	char path[PATH_MAX];
+	struct dirent *ent;
+	DIR *dir;
+
+#define for_each_memory(mem, dir)					\
+	while ((ent = readdir(dir)))					\
+		if (strcmp(ent->d_name, ".") &&				\
+		    strcmp(ent->d_name, "..") &&			\
+		    sscanf(ent->d_name, "memory%u", &mem) == 1)
+
+	scnprintf(path, PATH_MAX,
+		  "%s/devices/system/node/node%lu",
+		  sysfs__mountpoint(), index);
+
+	dir = opendir(path);
+	if (!dir) {
+		pr_warning("failed: cant' open memory sysfs data\n");
+		return -1;
+	}
+
+	for_each_memory(phys, dir) {
+		size = max(phys, size);
+	}
+
+	size++;
+
+	n->set = bitmap_alloc(size);
+	if (!n->set) {
+		closedir(dir);
+		return -ENOMEM;
+	}
+
+	bitmap_zero(n->set, size);
+	n->node = index;
+	n->size = size;
+
+	rewinddir(dir);
+
+	for_each_memory(phys, dir) {
+		set_bit(phys, n->set);
+	}
+
+	closedir(dir);
+	return 0;
+}
+
+static int memory_node__sort(const void *a, const void *b)
+{
+	const struct memory_node *na = a;
+	const struct memory_node *nb = b;
+
+	return na->node - nb->node;
+}
+
+static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp)
+{
+	char path[PATH_MAX];
+	struct dirent *ent;
+	DIR *dir;
+	u64 cnt = 0;
+	int ret = 0;
+
+	scnprintf(path, PATH_MAX, "%s/devices/system/node/",
+		  sysfs__mountpoint());
+
+	dir = opendir(path);
+	if (!dir) {
+		pr_warning("failed: can't open node sysfs data\n");
+		return -1;
+	}
+
+	while (!ret && (ent = readdir(dir))) {
+		unsigned int index;
+		int r;
+
+		if (!strcmp(ent->d_name, ".") ||
+		    !strcmp(ent->d_name, ".."))
+			continue;
+
+		r = sscanf(ent->d_name, "node%u", &index);
+		if (r != 1)
+			continue;
+
+		if (WARN_ONCE(cnt >= size,
+			      "failed to write MEM_TOPOLOGY, way too many nodes\n"))
+			return -1;
+
+		ret = memory_node__read(&nodes[cnt++], index);
+	}
+
+	*cntp = cnt;
+	closedir(dir);
+
+	if (!ret)
+		qsort(nodes, cnt, sizeof(nodes[0]), memory_node__sort);
+
+	return ret;
+}
+
+#define MAX_MEMORY_NODES 2000
+
+/*
+ * The MEM_TOPOLOGY holds physical memory map for every
+ * node in system. The format of data is as follows:
+ *
+ *  0 - version          | for future changes
+ *  8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
+ * 16 - count            | number of nodes
+ *
+ * For each node we store map of physical indexes for
+ * each node:
+ *
+ * 32 - node id          | node index
+ * 40 - size             | size of bitmap
+ * 48 - bitmap           | bitmap of memory indexes that belongs to node
+ */
+static int write_mem_topology(struct feat_fd *ff __maybe_unused,
+			      struct perf_evlist *evlist __maybe_unused)
+{
+	static struct memory_node nodes[MAX_MEMORY_NODES];
+	u64 bsize, version = 1, i, nr;
+	int ret;
+
+	ret = sysfs__read_xll("devices/system/memory/block_size_bytes",
+			      (unsigned long long *) &bsize);
+	if (ret)
+		return ret;
+
+	ret = build_mem_topology(&nodes[0], MAX_MEMORY_NODES, &nr);
+	if (ret)
+		return ret;
+
+	ret = do_write(ff, &version, sizeof(version));
+	if (ret < 0)
+		goto out;
+
+	ret = do_write(ff, &bsize, sizeof(bsize));
+	if (ret < 0)
+		goto out;
+
+	ret = do_write(ff, &nr, sizeof(nr));
+	if (ret < 0)
+		goto out;
+
+	for (i = 0; i < nr; i++) {
+		struct memory_node *n = &nodes[i];
+
+		#define _W(v)						\
+			ret = do_write(ff, &n->v, sizeof(n->v));	\
+			if (ret < 0)					\
+				goto out;
+
+		_W(node)
+		_W(size)
+
+		#undef _W
+
+		ret = do_write_bitmap(ff, n->set, n->size);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
 static void print_hostname(struct feat_fd *ff, FILE *fp)
 {
 	fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname);
@@ -1543,6 +1766,35 @@ static void print_sample_time(struct feat_fd *ff, FILE *fp)
 	fprintf(fp, "# sample duration : %10.3f ms\n", d);
 }
 
+static void memory_node__fprintf(struct memory_node *n,
+				 unsigned long long bsize, FILE *fp)
+{
+	char buf_map[100], buf_size[50];
+	unsigned long long size;
+
+	size = bsize * bitmap_weight(n->set, n->size);
+	unit_number__scnprintf(buf_size, 50, size);
+
+	bitmap_scnprintf(n->set, n->size, buf_map, 100);
+	fprintf(fp, "#  %3" PRIu64 " [%s]: %s\n", n->node, buf_size, buf_map);
+}
+
+static void print_mem_topology(struct feat_fd *ff, FILE *fp)
+{
+	struct memory_node *nodes;
+	int i, nr;
+
+	nodes = ff->ph->env.memory_nodes;
+	nr    = ff->ph->env.nr_memory_nodes;
+
+	fprintf(fp, "# memory nodes (nr %d, block size 0x%llx):\n",
+		nr, ff->ph->env.memory_bsize);
+
+	for (i = 0; i < nr; i++) {
+		memory_node__fprintf(&nodes[i], ff->ph->env.memory_bsize, fp);
+	}
+}
+
 static int __event_process_build_id(struct build_id_event *bev,
 				    char *filename,
 				    struct perf_session *session)
@@ -2205,6 +2457,58 @@ static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
 	return 0;
 }
 
+static int process_mem_topology(struct feat_fd *ff,
+				void *data __maybe_unused)
+{
+	struct memory_node *nodes;
+	u64 version, i, nr, bsize;
+	int ret = -1;
+
+	if (do_read_u64(ff, &version))
+		return -1;
+
+	if (version != 1)
+		return -1;
+
+	if (do_read_u64(ff, &bsize))
+		return -1;
+
+	if (do_read_u64(ff, &nr))
+		return -1;
+
+	nodes = zalloc(sizeof(*nodes) * nr);
+	if (!nodes)
+		return -1;
+
+	for (i = 0; i < nr; i++) {
+		struct memory_node n;
+
+		#define _R(v)				\
+			if (do_read_u64(ff, &n.v))	\
+				goto out;		\
+
+		_R(node)
+		_R(size)
+
+		#undef _R
+
+		if (do_read_bitmap(ff, &n.set, &n.size))
+			goto out;
+
+		nodes[i] = n;
+	}
+
+	ff->ph->env.memory_bsize    = bsize;
+	ff->ph->env.memory_nodes    = nodes;
+	ff->ph->env.nr_memory_nodes = nr;
+	ret = 0;
+
+out:
+	if (ret)
+		free(nodes);
+	return ret;
+}
+
 struct feature_ops {
 	int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
 	void (*print)(struct feat_fd *ff, FILE *fp);
@@ -2263,6 +2567,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
 	FEAT_OPN(STAT,		stat,		false),
 	FEAT_OPN(CACHE,		cache,		true),
 	FEAT_OPR(SAMPLE_TIME,	sample_time,	false),
+	FEAT_OPR(MEM_TOPOLOGY,	mem_topology,	true),
 };
 
 struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 942bdec6d70d..90d4577a92dc 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -36,6 +36,7 @@ enum {
 	HEADER_STAT,
 	HEADER_CACHE,
 	HEADER_SAMPLE_TIME,
+	HEADER_MEM_TOPOLOGY,
 	HEADER_LAST_FEATURE,
 	HEADER_FEAT_BITS	= 256,
 };
-- 
2.13.6

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

* [PATCH 08/19] perf tools: Add mem2node object
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (6 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 19:27   ` Arnaldo Carvalho de Melo
  2018-03-07 15:50 ` [PATCH 09/19] perf tests: Add mem2node object test Jiri Olsa
                   ` (10 subsequent siblings)
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Adding mem2node object to allow the easy lookup
of the node for the physical address.

It has following interface:

  int  mem2node__init(struct mem2node *map, struct perf_env *env);
  void mem2node__exit(struct mem2node *map);
  int  mem2node__node(struct mem2node *map, u64 addr);

The mem2node__init initialize object from the perf data
file MEM_TOPOLOGY feature data. Following calls to
mem2node__node will return node number for given
physical address. The mem2node__exit function frees
the object.

Link: http://lkml.kernel.org/n/tip-qq7sohu774wxq154n3my037z@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/Build      |   1 +
 tools/perf/util/mem2node.c | 129 +++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/mem2node.h |  19 +++++++
 3 files changed, 149 insertions(+)
 create mode 100644 tools/perf/util/mem2node.c
 create mode 100644 tools/perf/util/mem2node.h

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index ea0a452550b0..8052373bcd6a 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -106,6 +106,7 @@ libperf-y += units.o
 libperf-y += time-utils.o
 libperf-y += expr-bison.o
 libperf-y += branch.o
+libperf-y += mem2node.o
 
 libperf-$(CONFIG_LIBBPF) += bpf-loader.o
 libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c
new file mode 100644
index 000000000000..6da8ddbb1182
--- /dev/null
+++ b/tools/perf/util/mem2node.c
@@ -0,0 +1,129 @@
+#include <errno.h>
+#include <inttypes.h>
+#include <linux/bitmap.h>
+#include "mem2node.h"
+#include "util.h"
+
+struct entry {
+	struct rb_node	rb_node;
+	u64	start;
+	u64	end;
+	u64	node;
+};
+
+static void entry__insert(struct entry *entry, struct rb_root *root)
+{
+	struct rb_node **p = &root->rb_node;
+	struct rb_node *parent = NULL;
+	struct entry *e;
+
+	while (*p != NULL) {
+		parent = *p;
+		e = rb_entry(parent, struct entry, rb_node);
+
+		if (entry->start < e->start)
+			p = &(*p)->rb_left;
+		else
+			p = &(*p)->rb_right;
+	}
+
+	rb_link_node(&entry->rb_node, parent, p);
+	rb_insert_color(&entry->rb_node, root);
+}
+
+int mem2node__init(struct mem2node *map, struct perf_env *env)
+{
+	struct memory_node *n, *nodes = &env->memory_nodes[0];
+	u64 bsize = env->memory_bsize;
+	struct entry *entry;
+	int i, j = 0, max = 0;
+
+	memset(map, 0x0, sizeof(*map));
+	map->root = RB_ROOT;
+
+	for (i = 0; i < env->nr_memory_nodes; i++) {
+		n = &nodes[i];
+		max += bitmap_weight(n->set, n->size);
+	}
+
+	entry = zalloc(sizeof(*entry) * max);
+	if (!entry)
+		return -ENOMEM;
+
+	for (i = 0; i < env->nr_memory_nodes; i++) {
+		u64 bit;
+
+		n = &nodes[i];
+
+		for (bit = 0; bit < n->size; bit++) {
+			u64 start;
+
+			if (!test_bit(bit, n->set))
+				continue;
+
+			start = bit * bsize;
+
+			/*
+			 * Merge nearby areas, we walk in order
+			 * through the bitmap, so no need to sort.
+			 */
+			if (j > 0) {
+				struct entry *prev = &entry[j - 1];
+
+				if ((prev->end == start) &&
+				    (prev->node == n->node)) {
+					prev->end += bsize;
+					continue;
+				}
+			}
+
+			entry[j].start = start;
+			entry[j].end   = start + bsize;
+			entry[j].node  = n->node;
+			RB_CLEAR_NODE(&entry[j].rb_node);
+			j++;
+		}
+	}
+
+	/* Cut unused entries, due to merging. */
+	entry = realloc(entry, sizeof(*entry) * j);
+	if (!entry)
+		return -ENOMEM;
+
+	for (i = 0; i < j; i++) {
+		pr_debug("mem2node %03" PRIu64 " [0x%016" PRIx64 "-0x%016" PRIx64 "]\n",
+			 entry[i].node, entry[i].start, entry[i].end);
+
+		entry__insert(&entry[i], &map->root);
+	}
+
+	map->entry = entry;
+	return 0;
+}
+
+void mem2node__exit(struct mem2node *map)
+{
+	zfree(&map->entry);
+}
+
+int mem2node__node(struct mem2node *map, u64 addr)
+{
+	struct rb_node **p, *parent = NULL;
+	struct entry *entry;
+
+	p = &map->root.rb_node;
+	while (*p != NULL) {
+		parent = *p;
+		entry = rb_entry(parent, struct entry, rb_node);
+		if (addr < entry->start)
+			p = &(*p)->rb_left;
+		else if (addr >= entry->end)
+			p = &(*p)->rb_right;
+		else
+			goto out;
+	}
+
+	entry = NULL;
+out:
+	return entry ? (int) entry->node : -1;
+}
diff --git a/tools/perf/util/mem2node.h b/tools/perf/util/mem2node.h
new file mode 100644
index 000000000000..e27333755a2c
--- /dev/null
+++ b/tools/perf/util/mem2node.h
@@ -0,0 +1,19 @@
+#ifndef __MEM2NODE_H
+#define __MEM2NODE_H
+
+#include <linux/rbtree.h>
+#include "env.h"
+
+struct entry;
+
+struct mem2node {
+	struct rb_root	 root;
+	struct entry	*entry;
+	int		 cnt;
+};
+
+int  mem2node__init(struct mem2node *map, struct perf_env *env);
+void mem2node__exit(struct mem2node *map);
+int  mem2node__node(struct mem2node *map, u64 addr);
+
+#endif /* __MEM2NODE_H */
-- 
2.13.6

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

* [PATCH 09/19] perf tests: Add mem2node object test
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (7 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 08/19] perf tools: Add mem2node object Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 10/19] perf c2c record: Record physical addresses in samples Jiri Olsa
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Adding mem2node object automated test.

The test prepares few artificial node - memory maps and
verifies the mem2node object returns proper node values
to given addresses.

Link: http://lkml.kernel.org/n/tip-17xdxr5k1zfca9o3fymowqa5@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 +++
 tools/perf/tests/mem2node.c     | 73 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 4 files changed, 79 insertions(+)
 create mode 100644 tools/perf/tests/mem2node.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 87bf3edb037c..45782220ac23 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -47,6 +47,7 @@ perf-y += bitmap.o
 perf-y += perf-hooks.o
 perf-y += clang.o
 perf-y += unit_number__scnprintf.o
+perf-y += mem2node.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index fafa014240cd..09071ef4434f 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -271,6 +271,10 @@ static struct test generic_tests[] = {
 		.func = test__unit_number__scnprint,
 	},
 	{
+		.desc = "mem2node",
+		.func = test__mem2node,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c
new file mode 100644
index 000000000000..c883607dcd22
--- /dev/null
+++ b/tools/perf/tests/mem2node.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/compiler.h>
+#include <linux/bitmap.h>
+#include "cpumap.h"
+#include "mem2node.h"
+#include "tests.h"
+
+static struct node {
+	int		 node;
+	const char 	*map;
+} test_nodes[] = {
+	{ .node = 0, .map = "0"     },
+	{ .node = 1, .map = "1-2"   },
+	{ .node = 3, .map = "5-7,9" },
+};
+
+#define T TEST_ASSERT_VAL
+
+static unsigned long *get_bitmap(const char *str, int nbits)
+{
+	struct cpu_map *map = cpu_map__new(str);
+	unsigned long *bm = NULL;
+	int i;
+
+	bm = bitmap_alloc(nbits);
+
+	if (map && bm) {
+		bitmap_zero(bm, nbits);
+
+		for (i = 0; i < map->nr; i++) {
+			set_bit(map->map[i], bm);
+		}
+	}
+
+	if (map)
+		cpu_map__put(map);
+	else
+		free(bm);
+
+	return bm && map ? bm : NULL;
+}
+
+int test__mem2node(struct test *t __maybe_unused, int subtest __maybe_unused)
+{
+	struct mem2node map;
+	struct memory_node nodes[3];
+	struct perf_env env = {
+		.memory_nodes    = (struct memory_node *) &nodes[0],
+		.nr_memory_nodes = ARRAY_SIZE(nodes),
+		.memory_bsize    = 0x100,
+	};
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(nodes); i++) {
+		nodes[i].node = test_nodes[i].node;
+		nodes[i].size = 10;
+
+		T("failed: alloc bitmap",
+		  (nodes[i].set = get_bitmap(test_nodes[i].map, 10)));
+	}
+
+	T("failed: mem2node__init", !mem2node__init(&map, &env));
+	T("failed: mem2node__node",  0 == mem2node__node(&map,   0x50));
+	T("failed: mem2node__node",  1 == mem2node__node(&map,  0x100));
+	T("failed: mem2node__node",  1 == mem2node__node(&map,  0x250));
+	T("failed: mem2node__node",  3 == mem2node__node(&map,  0x500));
+	T("failed: mem2node__node",  3 == mem2node__node(&map,  0x650));
+	T("failed: mem2node__node", -1 == mem2node__node(&map,  0x450));
+	T("failed: mem2node__node", -1 == mem2node__node(&map, 0x1050));
+
+	mem2node__exit(&map);
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 2862b80bc288..2e169819e647 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -102,6 +102,7 @@ int test__clang(struct test *test, int subtest);
 const char *test__clang_subtest_get_desc(int subtest);
 int test__clang_subtest_get_nr(void);
 int test__unit_number__scnprint(struct test *test, int subtest);
+int test__mem2node(struct test *t, int subtest);
 
 bool test__bp_signal_is_supported(void);
 
-- 
2.13.6

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

* [PATCH 10/19] perf c2c record: Record physical addresses in samples
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (8 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 09/19] perf tests: Add mem2node object test Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 11/19] perf c2c report: Make calc_width work with struct c2c_hist_entry Jiri Olsa
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

We are going to display NUMA node information in following
patches. For this we need to have physical address data in
the sample.

Adding --phys-data as a default option for perf c2c record.

Link: http://lkml.kernel.org/n/tip-4d4lyozdbsknzqeny8kl1jg4@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/Documentation/perf-c2c.txt | 2 +-
 tools/perf/builtin-c2c.c              | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-c2c.txt b/tools/perf/Documentation/perf-c2c.txt
index 822414235170..095aebdc5bb7 100644
--- a/tools/perf/Documentation/perf-c2c.txt
+++ b/tools/perf/Documentation/perf-c2c.txt
@@ -116,7 +116,7 @@ and calls standard perf record command.
 Following perf record options are configured by default:
 (check perf record man page for details)
 
-  -W,-d,--sample-cpu
+  -W,-d,--phys-data,--sample-cpu
 
 Unless specified otherwise with '-e' option, following events are monitored by
 default:
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 98d243fa0c06..95765a1db903 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2704,7 +2704,7 @@ static int perf_c2c__record(int argc, const char **argv)
 	argc = parse_options(argc, argv, options, record_mem_usage,
 			     PARSE_OPT_KEEP_UNKNOWN);
 
-	rec_argc = argc + 10; /* max number of arguments */
+	rec_argc = argc + 11; /* max number of arguments */
 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
 	if (!rec_argv)
 		return -1;
@@ -2720,6 +2720,7 @@ static int perf_c2c__record(int argc, const char **argv)
 		rec_argv[i++] = "-W";
 
 	rec_argv[i++] = "-d";
+	rec_argv[i++] = "--phys-data";
 	rec_argv[i++] = "--sample-cpu";
 
 	for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
-- 
2.13.6

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

* [PATCH 11/19] perf c2c report: Make calc_width work with struct c2c_hist_entry
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (9 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 10/19] perf c2c record: Record physical addresses in samples Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 12/19] perf c2c report: Call calc_width only for displayed entries Jiri Olsa
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

We are going to calculate column width based on the
struct c2c_hist_entry data, so making calc_width to
work with struct c2c_hist_entry.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 95765a1db903..43ce55550c9d 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -1839,20 +1839,24 @@ static inline int valid_hitm_or_store(struct hist_entry *he)
 	return has_hitm || c2c_he->stats.store;
 }
 
-static void calc_width(struct hist_entry *he)
+static void calc_width(struct c2c_hist_entry *c2c_he)
 {
 	struct c2c_hists *c2c_hists;
 
-	c2c_hists = container_of(he->hists, struct c2c_hists, hists);
-	hists__calc_col_len(&c2c_hists->hists, he);
+	c2c_hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);
+	hists__calc_col_len(&c2c_hists->hists, &c2c_he->he);
 }
 
 static int filter_cb(struct hist_entry *he)
 {
+	struct c2c_hist_entry *c2c_he;
+
+	c2c_he = container_of(he, struct c2c_hist_entry, he);
+
 	if (c2c.show_src && !he->srcline)
 		he->srcline = hist_entry__get_srcline(he);
 
-	calc_width(he);
+	calc_width(c2c_he);
 
 	if (!valid_hitm_or_store(he))
 		he->filtered = HIST_FILTER__C2C;
@@ -1869,7 +1873,7 @@ static int resort_cl_cb(struct hist_entry *he)
 	c2c_he = container_of(he, struct c2c_hist_entry, he);
 	c2c_hists = c2c_he->hists;
 
-	calc_width(he);
+	calc_width(c2c_he);
 
 	if (display && c2c_hists) {
 		static unsigned int idx;
-- 
2.13.6

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

* [PATCH 12/19] perf c2c report: Call calc_width only for displayed entries
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (10 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 11/19] perf c2c report: Make calc_width work with struct c2c_hist_entry Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 13/19] perf c2c report: Display node for cacheline address Jiri Olsa
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

There's no need to calculate column width on entries
that are not going to be displayed.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 43ce55550c9d..821112e8ba97 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -1873,12 +1873,11 @@ static int resort_cl_cb(struct hist_entry *he)
 	c2c_he = container_of(he, struct c2c_hist_entry, he);
 	c2c_hists = c2c_he->hists;
 
-	calc_width(c2c_he);
-
 	if (display && c2c_hists) {
 		static unsigned int idx;
 
 		c2c_he->cacheline_idx = idx++;
+		calc_width(c2c_he);
 
 		c2c_hists__reinit(c2c_hists, c2c.cl_output, c2c.cl_resort);
 
-- 
2.13.6

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

* [PATCH 13/19] perf c2c report: Display node for cacheline address
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (11 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 12/19] perf c2c report: Call calc_width only for displayed entries Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 14/19] perf c2c report: Add span header over cacheline data Jiri Olsa
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Adding the NUMA node info for the data cacheline. Adding
the new column to both Shared Data Cache Line Table and
Shared Cache Line Distribution Pareto.

Note the new 'Node' column next to the 'Cacheline'.

  $ perf c2c report --stdio
  =================================================
             Shared Data Cache Line Table
  =================================================
  #
  #                                    Total      Tot  ----- LLC Load Hitm -----
  # Index           Cacheline  Node  records     Hitm    Total      Lcl      Rmt
  # .....  ..................  ....  .......  .......  .......  .......  .......
  #
        0      0x7f0830100000     0       84   10.53%        8        8        0
        1  0xffff922a93154200     0        3    2.63%        2        2        0
        2  0xffff922a93154500     0        4    2.63%        2        2        0
  ...

Note the new 'Node' column next to the 'Offset'.

  =================================================
        Shared Cache Line Distribution Pareto
  =================================================
  #
  #        ----- HITM -----  -- Store Refs --        Data address
  #   Num      Rmt      Lcl   L1 Hit  L1 Miss              Offset  Node      Pid
  # .....  .......  .......  .......  .......  ..................  ....  .......
  #
    -------------------------------------------------------------
        0        0        8       32        2      0x7f0830100000
    -------------------------------------------------------------
             0.00%   75.00%   21.88%    0.00%                0x18     0     1791
             0.00%   12.50%   37.50%    0.00%                0x18     0     1791
             0.00%    0.00%   34.38%    0.00%                0x18     0     1791

Using the mem2node object to get the NUMA node data.

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 821112e8ba97..45c047fdd7ac 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -32,6 +32,7 @@
 #include "evsel.h"
 #include "ui/browsers/hists.h"
 #include "thread.h"
+#include "mem2node.h"
 
 struct c2c_hists {
 	struct hists		hists;
@@ -49,6 +50,7 @@ struct c2c_hist_entry {
 	struct c2c_hists	*hists;
 	struct c2c_stats	 stats;
 	unsigned long		*cpuset;
+	unsigned long		*nodeset;
 	struct c2c_stats	*node_stats;
 	unsigned int		 cacheline_idx;
 
@@ -59,6 +61,11 @@ struct c2c_hist_entry {
 	 * because of its callchain dynamic entry
 	 */
 	struct hist_entry	he;
+
+	unsigned long		 paddr;
+	unsigned long		 paddr_cnt;
+	bool			 paddr_zero;
+	char			*nodestr;
 };
 
 static char const *coalesce_default = "pid,iaddr";
@@ -66,6 +73,7 @@ static char const *coalesce_default = "pid,iaddr";
 struct perf_c2c {
 	struct perf_tool	tool;
 	struct c2c_hists	hists;
+	struct mem2node		mem2node;
 
 	unsigned long		**nodes;
 	int			 nodes_cnt;
@@ -123,6 +131,10 @@ static void *c2c_he_zalloc(size_t size)
 	if (!c2c_he->cpuset)
 		return NULL;
 
+	c2c_he->nodeset = bitmap_alloc(c2c.nodes_cnt);
+	if (!c2c_he->nodeset)
+		return NULL;
+
 	c2c_he->node_stats = zalloc(c2c.nodes_cnt * sizeof(*c2c_he->node_stats));
 	if (!c2c_he->node_stats)
 		return NULL;
@@ -145,6 +157,8 @@ static void c2c_he_free(void *he)
 	}
 
 	free(c2c_he->cpuset);
+	free(c2c_he->nodeset);
+	free(c2c_he->nodestr);
 	free(c2c_he->node_stats);
 	free(c2c_he);
 }
@@ -194,6 +208,28 @@ static void c2c_he__set_cpu(struct c2c_hist_entry *c2c_he,
 	set_bit(sample->cpu, c2c_he->cpuset);
 }
 
+static void c2c_he__set_node(struct c2c_hist_entry *c2c_he,
+			     struct perf_sample *sample)
+{
+	int node;
+
+	if (!sample->phys_addr) {
+		c2c_he->paddr_zero = true;
+		return;
+	}
+
+	node = mem2node__node(&c2c.mem2node, sample->phys_addr);
+	if (WARN_ONCE(node < 0, "WARNING: failed to find node\n"))
+		return;
+
+	set_bit(node, c2c_he->nodeset);
+
+	if (c2c_he->paddr != sample->phys_addr) {
+		c2c_he->paddr_cnt++;
+		c2c_he->paddr = sample->phys_addr;
+	}
+}
+
 static void compute_stats(struct c2c_hist_entry *c2c_he,
 			  struct c2c_stats *stats,
 			  u64 weight)
@@ -257,6 +293,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 	c2c_add_stats(&c2c_hists->stats, &stats);
 
 	c2c_he__set_cpu(c2c_he, sample);
+	c2c_he__set_node(c2c_he, sample);
 
 	hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
 	ret = hist_entry__append_callchain(he, sample);
@@ -293,6 +330,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 		compute_stats(c2c_he, &stats, sample->weight);
 
 		c2c_he__set_cpu(c2c_he, sample);
+		c2c_he__set_node(c2c_he, sample);
 
 		hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
 		ret = hist_entry__append_callchain(he, sample);
@@ -455,6 +493,20 @@ static int dcacheline_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
 }
 
+static int
+dcacheline_node_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);
+	if (WARN_ON_ONCE(!c2c_he->nodestr))
+		return 0;
+
+	return scnprintf(hpp->buf, hpp->size, "%*s", width, c2c_he->nodestr);
+}
+
 static int offset_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 			struct hist_entry *he)
 {
@@ -1207,6 +1259,14 @@ static struct c2c_dimension dim_dcacheline = {
 	.width		= 18,
 };
 
+static struct c2c_dimension dim_dcacheline_node = {
+	.header		= HEADER_LOW("Node"),
+	.name		= "dcacheline_node",
+	.cmp		= empty_cmp,
+	.entry		= dcacheline_node_entry,
+	.width		= 4,
+};
+
 static struct c2c_header header_offset_tui = HEADER_LOW("Off");
 
 static struct c2c_dimension dim_offset = {
@@ -1217,6 +1277,14 @@ static struct c2c_dimension dim_offset = {
 	.width		= 18,
 };
 
+static struct c2c_dimension dim_offset_node = {
+	.header		= HEADER_LOW("Node"),
+	.name		= "offset_node",
+	.cmp		= empty_cmp,
+	.entry		= dcacheline_node_entry,
+	.width		= 4,
+};
+
 static struct c2c_dimension dim_iaddr = {
 	.header		= HEADER_LOW("Code address"),
 	.name		= "iaddr",
@@ -1536,7 +1604,9 @@ static struct c2c_dimension dim_dcacheline_num_empty = {
 
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
+	&dim_dcacheline_node,
 	&dim_offset,
+	&dim_offset_node,
 	&dim_iaddr,
 	&dim_tot_hitm,
 	&dim_lcl_hitm,
@@ -1839,12 +1909,44 @@ static inline int valid_hitm_or_store(struct hist_entry *he)
 	return has_hitm || c2c_he->stats.store;
 }
 
+static void set_node_width(struct c2c_hist_entry *c2c_he, int len)
+{
+	struct c2c_dimension *dim;
+
+	dim = &c2c.hists == c2c_he->hists ?
+	      &dim_dcacheline_node : &dim_offset_node;
+
+	if (len > dim->width)
+		dim->width = len;
+}
+
+static int set_nodestr(struct c2c_hist_entry *c2c_he)
+{
+	char buf[30];
+	int len;
+
+	if (c2c_he->nodestr)
+		return 0;
+
+	if (bitmap_weight(c2c_he->nodeset, c2c.nodes_cnt)) {
+		len = bitmap_scnprintf(c2c_he->nodeset, c2c.nodes_cnt,
+				      buf, sizeof(buf));
+	} else {
+		len = scnprintf(buf, sizeof(buf), "N/A");
+	}
+
+	set_node_width(c2c_he, len);
+	c2c_he->nodestr = strdup(buf);
+	return c2c_he->nodestr ? 0 : -ENOMEM;
+}
+
 static void calc_width(struct c2c_hist_entry *c2c_he)
 {
 	struct c2c_hists *c2c_hists;
 
 	c2c_hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);
 	hists__calc_col_len(&c2c_hists->hists, &c2c_he->he);
+	set_nodestr(c2c_he);
 }
 
 static int filter_cb(struct hist_entry *he)
@@ -2474,7 +2576,7 @@ static int build_cl_output(char *cl_sort, bool no_source)
 		"percent_lcl_hitm,"
 		"percent_stores_l1hit,"
 		"percent_stores_l1miss,"
-		"offset,",
+		"offset,offset_node,",
 		add_pid   ? "pid," : "",
 		add_tid   ? "tid," : "",
 		add_iaddr ? "iaddr," : "",
@@ -2603,17 +2705,21 @@ static int perf_c2c__report(int argc, const char **argv)
 		goto out;
 	}
 
-	err = setup_callchain(session->evlist);
+	err = mem2node__init(&c2c.mem2node, &session->header.env);
 	if (err)
 		goto out_session;
 
+	err = setup_callchain(session->evlist);
+	if (err)
+		goto out_mem2node;
+
 	if (symbol__init(&session->header.env) < 0)
-		goto out_session;
+		goto out_mem2node;
 
 	/* No pipe support at the moment. */
 	if (perf_data__is_pipe(session->data)) {
 		pr_debug("No pipe support at the moment.\n");
-		goto out_session;
+		goto out_mem2node;
 	}
 
 	if (c2c.use_stdio)
@@ -2626,12 +2732,13 @@ static int perf_c2c__report(int argc, const char **argv)
 	err = perf_session__process_events(session);
 	if (err) {
 		pr_err("failed to process sample\n");
-		goto out_session;
+		goto out_mem2node;
 	}
 
 	c2c_hists__reinit(&c2c.hists,
 			"cl_idx,"
 			"dcacheline,"
+			"dcacheline_node,"
 			"tot_recs,"
 			"percent_hitm,"
 			"tot_hitm,lcl_hitm,rmt_hitm,"
@@ -2657,6 +2764,8 @@ static int perf_c2c__report(int argc, const char **argv)
 
 	perf_c2c_display(session);
 
+out_mem2node:
+	mem2node__exit(&c2c.mem2node);
 out_session:
 	perf_session__delete(session);
 out:
-- 
2.13.6

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

* [PATCH 14/19] perf c2c report: Add span header over cacheline data
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (12 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 13/19] perf c2c report: Display node for cacheline address Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 15/19] perf c2c report: Add cacheline address count column Jiri Olsa
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Forcing the NUMA node output to be grouped with the Cacheline
column in both Shared Data Cache Line Table and Shared Cache
Line Distribution Pareto.

Before:
  #                                    Total      Tot  ----- LLC Load Hitm -----
  # Index           Cacheline  Node  records     Hitm    Total      Lcl      Rmt
  # .....  ..................  ....  .......  .......  .......  .......  .......
  #
        0      0x7f0830100000     0       84   10.53%        8        8        0
        1  0xffff922a93154200     0        3    2.63%        2        2        0
        2  0xffff922a93154500     0        4    2.63%        2        2        0

After:
  #        ------- Cacheline ------    Total      Tot  ----- LLC Load Hitm -----
  # Index             Address  Node  records     Hitm    Total      Lcl      Rmt
  # .....  ..................  ....  .......  .......  .......  .......  .......
  #
        0      0x7f0830100000     0       84   10.53%        8        8        0
        1  0xffff922a93154200     0        3    2.63%        2        2        0
        2  0xffff922a93154500     0        4    2.63%        2        2        0

Before:
  #        ----- HITM -----  -- Store Refs --        Data address
  #   Num      Rmt      Lcl   L1 Hit  L1 Miss              Offset  Node      Pid
  # .....  .......  .......  .......  .......  ..................  ....  .......
  #
    -------------------------------------------------------------
        0        0        8       32        2      0x7f0830100000
    -------------------------------------------------------------
             0.00%   75.00%   21.88%    0.00%                0x18     0     1791
             0.00%   12.50%   37.50%    0.00%                0x18     0     1791
             0.00%    0.00%   34.38%    0.00%                0x18     0     1791

After:
  #        ----- HITM -----  -- Store Refs --  ----- Data address -----
  #   Num      Rmt      Lcl   L1 Hit  L1 Miss              Offset  Node      Pid
  # .....  .......  .......  .......  .......  ..................  ....  .......
  #
    -------------------------------------------------------------
        0        0        8       32        2      0x7f0830100000
    -------------------------------------------------------------
             0.00%   75.00%   21.88%    0.00%                0x18     0     1791
             0.00%   12.50%   37.50%    0.00%                0x18     0     1791
             0.00%    0.00%   34.38%    0.00%                0x18     0     1791

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 45c047fdd7ac..3790a7e0c51d 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -1252,7 +1252,7 @@ cl_idx_empty_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	}
 
 static struct c2c_dimension dim_dcacheline = {
-	.header		= HEADER_LOW("Cacheline"),
+	.header		= HEADER_SPAN("--- Cacheline ----", "Address", 1),
 	.name		= "dcacheline",
 	.cmp		= dcacheline_cmp,
 	.entry		= dcacheline_entry,
@@ -1267,10 +1267,10 @@ static struct c2c_dimension dim_dcacheline_node = {
 	.width		= 4,
 };
 
-static struct c2c_header header_offset_tui = HEADER_LOW("Off");
+static struct c2c_header header_offset_tui = HEADER_SPAN("-----", "Off", 1);
 
 static struct c2c_dimension dim_offset = {
-	.header		= HEADER_BOTH("Data address", "Offset"),
+	.header		= HEADER_SPAN("--- Data address -", "Offset", 1),
 	.name		= "offset",
 	.cmp		= offset_cmp,
 	.entry		= offset_entry,
@@ -2453,14 +2453,66 @@ static void perf_c2c_display(struct perf_session *session)
 }
 #endif /* HAVE_SLANG_SUPPORT */
 
-static void ui_quirks(void)
+static char *fill_line(const char *orig, int len)
 {
+	int i, j, olen = strlen(orig);
+	char *buf;
+
+	buf = zalloc(len + 1);
+	if (!buf)
+		return NULL;
+
+	j = len / 2 - olen / 2;
+
+	for (i = 0; i < j - 1; i++) {
+		buf[i] = '-';
+	}
+
+	buf[i++] = ' ';
+
+	strcpy(buf + i, orig);
+
+	i += olen;
+
+	buf[i++] = ' ';
+
+	for (; i < len; i++) {
+		buf[i] = '-';
+	}
+
+	return buf;
+}
+
+static int ui_quirks(void)
+{
+	const char *nodestr = "Data address";
+	char *buf;
+
 	if (!c2c.use_stdio) {
 		dim_offset.width  = 5;
 		dim_offset.header = header_offset_tui;
+		nodestr = "CL";
 	}
 
 	dim_percent_hitm.header = percent_hitm_header[c2c.display];
+
+	/* Fix the zero line for dcacheline column. */
+	buf = fill_line("Cacheline", dim_dcacheline.width +
+				     dim_dcacheline_node.width + 2);
+	if (!buf)
+		return -ENOMEM;
+
+	dim_dcacheline.header.line[0].text = buf;
+
+	/* Fix the zero line for offset column. */
+	buf = fill_line(nodestr, dim_offset.width +
+			      dim_offset_node.width + 2);
+	if (!buf)
+		return -ENOMEM;
+
+	dim_offset.header.line[0].text = buf;
+
+	return 0;
 }
 
 #define CALLCHAIN_DEFAULT_OPT  "graph,0.5,caller,function,percent"
@@ -2760,7 +2812,10 @@ static int perf_c2c__report(int argc, const char **argv)
 
 	ui_progress__finish();
 
-	ui_quirks();
+	if (ui_quirks()) {
+		pr_err("failed to setup UI\n");
+		goto out_mem2node;
+	}
 
 	perf_c2c_display(session);
 
-- 
2.13.6

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

* [PATCH 15/19] perf c2c report: Add cacheline address count column
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (13 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 14/19] perf c2c report: Add span header over cacheline data Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 15:50 ` [PATCH 16/19] perf tools: Update tags with .cpp files Jiri Olsa
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Adding the 'PA cnt' column grouped under data cacheline address.

It shows how many times the physical addresses changed for the
hist entry. It does not show the number of different physical
addresses for entry, because we don't store those. We only track
the number of times we got different address than we currently
hold, which is not expensive and gives similar info.

  $ perf c2c report --stdio

  #        ----------- Cacheline ----------    Total      Tot  ----- LLC Load Hitm -----
  # Index             Address  Node  PA cnt  records     Hitm    Total      Lcl      Rmt
  # .....  ..................  ....  ......  .......  .......  .......  .......  .......
  #
        0  0xffff9ad56dca0a80     0       9       10    7.69%        2        2        0
        1  0xffff9ad56dce0a80     0       9        9    7.69%        2        2        0
        2  0xffff9ad37659ad80     0       1        2    3.85%        1        1        0

  ...

  #        ----- HITM -----  -- Store Refs --  --------- Data address ---------
  #   Num      Rmt      Lcl   L1 Hit  L1 Miss              Offset  Node  PA cnt      Pid
  # .....  .......  .......  .......  .......  ..................  ....  ......  .......
  #
    -------------------------------------------------------------
        0        0        2        3        0  0xffff9ad56dca0a80
    -------------------------------------------------------------
             0.00%    0.00%   33.33%    0.00%                 0x0     0       1     2510
             0.00%    0.00%   33.33%    0.00%                 0x4     0       1     2476
             0.00%    0.00%   33.33%    0.00%                0x20     0       1        0
             0.00%  100.00%    0.00%    0.00%                0x38     0       1        0

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

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 3790a7e0c51d..5a0f5067dfe9 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -507,6 +507,17 @@ dcacheline_node_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	return scnprintf(hpp->buf, hpp->size, "%*s", width, c2c_he->nodestr);
 }
 
+static int
+dcacheline_node_count(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 scnprintf(hpp->buf, hpp->size, "%*lu", width, c2c_he->paddr_cnt);
+}
+
 static int offset_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 			struct hist_entry *he)
 {
@@ -1252,7 +1263,7 @@ cl_idx_empty_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	}
 
 static struct c2c_dimension dim_dcacheline = {
-	.header		= HEADER_SPAN("--- Cacheline ----", "Address", 1),
+	.header		= HEADER_SPAN("--- Cacheline ----", "Address", 2),
 	.name		= "dcacheline",
 	.cmp		= dcacheline_cmp,
 	.entry		= dcacheline_entry,
@@ -1267,10 +1278,18 @@ static struct c2c_dimension dim_dcacheline_node = {
 	.width		= 4,
 };
 
-static struct c2c_header header_offset_tui = HEADER_SPAN("-----", "Off", 1);
+static struct c2c_dimension dim_dcacheline_count = {
+	.header		= HEADER_LOW("PA cnt"),
+	.name		= "dcacheline_count",
+	.cmp		= empty_cmp,
+	.entry		= dcacheline_node_count,
+	.width		= 6,
+};
+
+static struct c2c_header header_offset_tui = HEADER_SPAN("-----", "Off", 2);
 
 static struct c2c_dimension dim_offset = {
-	.header		= HEADER_SPAN("--- Data address -", "Offset", 1),
+	.header		= HEADER_SPAN("--- Data address -", "Offset", 2),
 	.name		= "offset",
 	.cmp		= offset_cmp,
 	.entry		= offset_entry,
@@ -1605,6 +1624,7 @@ static struct c2c_dimension dim_dcacheline_num_empty = {
 static struct c2c_dimension *dimensions[] = {
 	&dim_dcacheline,
 	&dim_dcacheline_node,
+	&dim_dcacheline_count,
 	&dim_offset,
 	&dim_offset_node,
 	&dim_iaddr,
@@ -2498,7 +2518,8 @@ static int ui_quirks(void)
 
 	/* Fix the zero line for dcacheline column. */
 	buf = fill_line("Cacheline", dim_dcacheline.width +
-				     dim_dcacheline_node.width + 2);
+				     dim_dcacheline_node.width +
+				     dim_dcacheline_count.width + 4);
 	if (!buf)
 		return -ENOMEM;
 
@@ -2506,7 +2527,8 @@ static int ui_quirks(void)
 
 	/* Fix the zero line for offset column. */
 	buf = fill_line(nodestr, dim_offset.width +
-			      dim_offset_node.width + 2);
+			         dim_offset_node.width +
+				 dim_dcacheline_count.width + 4);
 	if (!buf)
 		return -ENOMEM;
 
@@ -2628,7 +2650,7 @@ static int build_cl_output(char *cl_sort, bool no_source)
 		"percent_lcl_hitm,"
 		"percent_stores_l1hit,"
 		"percent_stores_l1miss,"
-		"offset,offset_node,",
+		"offset,offset_node,dcacheline_count,",
 		add_pid   ? "pid," : "",
 		add_tid   ? "tid," : "",
 		add_iaddr ? "iaddr," : "",
@@ -2791,6 +2813,7 @@ static int perf_c2c__report(int argc, const char **argv)
 			"cl_idx,"
 			"dcacheline,"
 			"dcacheline_node,"
+			"dcacheline_count,"
 			"tot_recs,"
 			"percent_hitm,"
 			"tot_hitm,lcl_hitm,rmt_hitm,"
-- 
2.13.6

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

* [PATCH 16/19] perf tools: Update tags with .cpp files
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (14 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 15/19] perf c2c report: Add cacheline address count column Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 19:28   ` Arnaldo Carvalho de Melo
  2018-03-09  8:55   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 17/19] perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA Jiri Olsa
                   ` (2 subsequent siblings)
  18 siblings, 2 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

We have some .cpp files, make ctags/cscope aware of them.

Link: http://lkml.kernel.org/n/tip-37og2tumxswqeyx0htq3zu04@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/Makefile.perf | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 4679e237a7f5..f7517e1b73f8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -708,15 +708,15 @@ TAG_FILES= ../../include/uapi/linux/perf_event.h
 
 TAGS:
 	$(QUIET_GEN)$(RM) TAGS; \
-	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs etags -a $(TAG_FILES)
+	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs etags -a $(TAG_FILES)
 
 tags:
 	$(QUIET_GEN)$(RM) tags; \
-	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs ctags -a $(TAG_FILES)
+	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs ctags -a $(TAG_FILES)
 
 cscope:
 	$(QUIET_GEN)$(RM) cscope*; \
-	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs cscope -b $(TAG_FILES)
+	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs cscope -b $(TAG_FILES)
 
 ### Testing rules
 
-- 
2.13.6

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

* [PATCH 17/19] perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (15 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 16/19] perf tools: Update tags with .cpp files Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:55   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 18/19] perf build: Add llvm/clang make targets to FILES Jiri Olsa
  2018-03-07 15:50 ` [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output Jiri Olsa
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

So we can see the status when we build perf, like:

  $ make LIBCLANGLLVM=1 VF=1
  ...                           cxx: [ on  ]
  ...                          llvm: [ on  ]
  ...                  llvm-version: [ on  ]
  ...                         clang: [ on  ]

Link: http://lkml.kernel.org/n/tip-geuvqz2pe5hh75bgbvar9sio@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/build/Makefile.feature | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index c378f003b007..5b6dda3b1ca8 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -82,7 +82,11 @@ FEATURE_TESTS_EXTRA :=                  \
          liberty-z                      \
          libunwind-debug-frame          \
          libunwind-debug-frame-arm      \
-         libunwind-debug-frame-aarch64
+         libunwind-debug-frame-aarch64  \
+         cxx                            \
+         llvm                           \
+         llvm-version                   \
+         clang
 
 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
 
-- 
2.13.6

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

* [PATCH 18/19] perf build: Add llvm/clang make targets to FILES
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (16 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 17/19] perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-09  8:56   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2018-03-07 15:50 ` [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output Jiri Olsa
  18 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

So they can follow the OUTPUT variable setup as the
rest of the features.

Link: http://lkml.kernel.org/n/tip-9i5z6mkc9i4ivmtc8b078nqu@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/build/feature/Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 0a490cb15149..f8ad640ffe5d 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -54,7 +54,10 @@ FILES=                                          \
          test-jvmti.bin				\
          test-sched_getcpu.bin			\
          test-setns.bin				\
-         test-libopencsd.bin
+         test-libopencsd.bin			\
+         test-clang.bin				\
+         test-llvm.bin				\
+         test-llvm-version.bin
 
 FILES := $(addprefix $(OUTPUT),$(FILES))
 
-- 
2.13.6

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

* [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output
  2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
                   ` (17 preceding siblings ...)
  2018-03-07 15:50 ` [PATCH 18/19] perf build: Add llvm/clang make targets to FILES Jiri Olsa
@ 2018-03-07 15:50 ` Jiri Olsa
  2018-03-07 19:30   ` Arnaldo Carvalho de Melo
  2018-03-09  8:56   ` [tip:perf/core] " tip-bot for Jiri Olsa
  18 siblings, 2 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-07 15:50 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

So we can see the output of feature compile
in following files:

  tools/build/feature/test-llvm.make.output
  tools/build/feature/test-llvm-version.make.output
  tools/build/feature/test-clang.make.output

Link: http://lkml.kernel.org/n/tip-z270blatcsc718tkv3zpwfx7@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/build/feature/Makefile | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index f8ad640ffe5d..dac9563b5470 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -260,11 +260,13 @@ $(OUTPUT)test-llvm.bin:
 		-I$(shell $(LLVM_CONFIG) --includedir) 		\
 		-L$(shell $(LLVM_CONFIG) --libdir)		\
 		$(shell $(LLVM_CONFIG) --libs Core BPF)		\
-		$(shell $(LLVM_CONFIG) --system-libs)
+		$(shell $(LLVM_CONFIG) --system-libs)		\
+		> $(@:.bin=.make.output) 2>&1
 
 $(OUTPUT)test-llvm-version.bin:
 	$(BUILDXX) -std=gnu++11 				\
-		-I$(shell $(LLVM_CONFIG) --includedir)
+		-I$(shell $(LLVM_CONFIG) --includedir)		\
+		> $(@:.bin=.make.output) 2>&1
 
 $(OUTPUT)test-clang.bin:
 	$(BUILDXX) -std=gnu++11 				\
@@ -274,7 +276,8 @@ $(OUTPUT)test-clang.bin:
 		  -lclangFrontend -lclangEdit -lclangLex	\
 		  -lclangAST -Wl,--end-group 			\
 		$(shell $(LLVM_CONFIG) --libs Core option)	\
-		$(shell $(LLVM_CONFIG) --system-libs)
+		$(shell $(LLVM_CONFIG) --system-libs)		\
+		> $(@:.bin=.make.output) 2>&1
 
 -include $(OUTPUT)*.d
 
-- 
2.13.6

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

* Re: [PATCH 05/19] perf tools: Add refcnt into struct mem_info
  2018-03-07 15:50 ` [PATCH 05/19] perf tools: Add refcnt into struct mem_info Jiri Olsa
@ 2018-03-07 18:56   ` Arnaldo Carvalho de Melo
  2018-03-08 10:59     ` Jiri Olsa
  2018-03-09  8:53   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 1 reply; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-07 18:56 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Em Wed, Mar 07, 2018 at 04:50:06PM +0100, Jiri Olsa escreveu:
> It's passed along several hists entries in --hierarchy mode,
> so it's better we keep track of it.

I like this, but you called it...
 
> +
> +struct mem_info *mem_info__aloc(void)
> +{
> +	struct mem_info *mi = zalloc(sizeof(*mi));
> +
> +	if (mi)
> +		refcount_set(&mi->refcnt, 1);
> +	return mi;

"aloc" with just one 'l', so I have to fix the typo, while at it I'll
use what is used elsewhere for this operation, i.e.

struct mem_info *mem_info__new(void);

:-)

- Arnaldo

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

* Re: [PATCH 08/19] perf tools: Add mem2node object
  2018-03-07 15:50 ` [PATCH 08/19] perf tools: Add mem2node object Jiri Olsa
@ 2018-03-07 19:27   ` Arnaldo Carvalho de Melo
  2018-03-08 11:03     ` Jiri Olsa
  0 siblings, 1 reply; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-07 19:27 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Em Wed, Mar 07, 2018 at 04:50:09PM +0100, Jiri Olsa escreveu:
> Adding mem2node object to allow the easy lookup
> of the node for the physical address.
> 
> It has following interface:
> 
>   int  mem2node__init(struct mem2node *map, struct perf_env *env);
>   void mem2node__exit(struct mem2node *map);
>   int  mem2node__node(struct mem2node *map, u64 addr);
> 
> The mem2node__init initialize object from the perf data
> file MEM_TOPOLOGY feature data. Following calls to
> mem2node__node will return node number for given
> physical address. The mem2node__exit function frees
> the object.
> 
> Link: http://lkml.kernel.org/n/tip-qq7sohu774wxq154n3my037z@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/Build      |   1 +
>  tools/perf/util/mem2node.c | 129 +++++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/mem2node.h |  19 +++++++
>  3 files changed, 149 insertions(+)
>  create mode 100644 tools/perf/util/mem2node.c
>  create mode 100644 tools/perf/util/mem2node.h
> 
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index ea0a452550b0..8052373bcd6a 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -106,6 +106,7 @@ libperf-y += units.o
>  libperf-y += time-utils.o
>  libperf-y += expr-bison.o
>  libperf-y += branch.o
> +libperf-y += mem2node.o
>  
>  libperf-$(CONFIG_LIBBPF) += bpf-loader.o
>  libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
> diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c
> new file mode 100644
> index 000000000000..6da8ddbb1182
> --- /dev/null
> +++ b/tools/perf/util/mem2node.c
> @@ -0,0 +1,129 @@
> +#include <errno.h>
> +#include <inttypes.h>
> +#include <linux/bitmap.h>
> +#include "mem2node.h"
> +#include "util.h"
> +
> +struct entry {
> +	struct rb_node	rb_node;
> +	u64	start;
> +	u64	end;
> +	u64	node;
> +};

Hey, this name is way too generic, please rename it to something more
descriptive

> +
> +static void entry__insert(struct entry *entry, struct rb_root *root)
> +{
> +	struct rb_node **p = &root->rb_node;
> +	struct rb_node *parent = NULL;
> +	struct entry *e;
> +
> +	while (*p != NULL) {
> +		parent = *p;
> +		e = rb_entry(parent, struct entry, rb_node);
> +
> +		if (entry->start < e->start)
> +			p = &(*p)->rb_left;
> +		else
> +			p = &(*p)->rb_right;
> +	}
> +
> +	rb_link_node(&entry->rb_node, parent, p);
> +	rb_insert_color(&entry->rb_node, root);
> +}
> +
> +int mem2node__init(struct mem2node *map, struct perf_env *env)
> +{
> +	struct memory_node *n, *nodes = &env->memory_nodes[0];
> +	u64 bsize = env->memory_bsize;
> +	struct entry *entry;
> +	int i, j = 0, max = 0;
> +
> +	memset(map, 0x0, sizeof(*map));
> +	map->root = RB_ROOT;
> +
> +	for (i = 0; i < env->nr_memory_nodes; i++) {
> +		n = &nodes[i];
> +		max += bitmap_weight(n->set, n->size);
> +	}
> +
> +	entry = zalloc(sizeof(*entry) * max);
> +	if (!entry)
> +		return -ENOMEM;

Also this is not an 'entry', but max ones, please rename this variable
to 'entries'.

> +
> +	for (i = 0; i < env->nr_memory_nodes; i++) {
> +		u64 bit;
> +
> +		n = &nodes[i];
> +
> +		for (bit = 0; bit < n->size; bit++) {
> +			u64 start;
> +
> +			if (!test_bit(bit, n->set))
> +				continue;
> +
> +			start = bit * bsize;
> +
> +			/*
> +			 * Merge nearby areas, we walk in order
> +			 * through the bitmap, so no need to sort.
> +			 */
> +			if (j > 0) {
> +				struct entry *prev = &entry[j - 1];
> +
> +				if ((prev->end == start) &&
> +				    (prev->node == n->node)) {
> +					prev->end += bsize;
> +					continue;
> +				}
> +			}
> +
> +			entry[j].start = start;
> +			entry[j].end   = start + bsize;
> +			entry[j].node  = n->node;
> +			RB_CLEAR_NODE(&entry[j].rb_node);

The previous four line could be done via the usual:

			krava_entry__init(&entries[j], start, bsize, n->node);

> +			j++;
> +		}
> +	}
> +
> +	/* Cut unused entries, due to merging. */
> +	entry = realloc(entry, sizeof(*entry) * j);
> +	if (!entry)
> +		return -ENOMEM;


Humm, so you lose it when not able to cut it short? Why not:

	nentries = realloc(entries, sizeof(entries[0) * j);
	if (nentries)
		entries = nentries;

And if you couldn't cut it (however unlikely that is) just go on and use
what you have already.

> +
> +	for (i = 0; i < j; i++) {
> +		pr_debug("mem2node %03" PRIu64 " [0x%016" PRIx64 "-0x%016" PRIx64 "]\n",
> +			 entry[i].node, entry[i].start, entry[i].end);
> +
> +		entry__insert(&entry[i], &map->root);
> +	}
> +
> +	map->entry = entry;
> +	return 0;
> +}
> +
> +void mem2node__exit(struct mem2node *map)
> +{
> +	zfree(&map->entry);
> +}
> +
> +int mem2node__node(struct mem2node *map, u64 addr)
> +{
> +	struct rb_node **p, *parent = NULL;
> +	struct entry *entry;
> +
> +	p = &map->root.rb_node;
> +	while (*p != NULL) {
> +		parent = *p;
> +		entry = rb_entry(parent, struct entry, rb_node);
> +		if (addr < entry->start)
> +			p = &(*p)->rb_left;
> +		else if (addr >= entry->end)
> +			p = &(*p)->rb_right;
> +		else
> +			goto out;
> +	}
> +
> +	entry = NULL;
> +out:
> +	return entry ? (int) entry->node : -1;
> +}
> diff --git a/tools/perf/util/mem2node.h b/tools/perf/util/mem2node.h
> new file mode 100644
> index 000000000000..e27333755a2c
> --- /dev/null
> +++ b/tools/perf/util/mem2node.h
> @@ -0,0 +1,19 @@
> +#ifndef __MEM2NODE_H
> +#define __MEM2NODE_H
> +
> +#include <linux/rbtree.h>
> +#include "env.h"
> +
> +struct entry;
> +
> +struct mem2node {
> +	struct rb_root	 root;
> +	struct entry	*entry;
> +	int		 cnt;
> +};
> +
> +int  mem2node__init(struct mem2node *map, struct perf_env *env);
> +void mem2node__exit(struct mem2node *map);
> +int  mem2node__node(struct mem2node *map, u64 addr);
> +
> +#endif /* __MEM2NODE_H */
> -- 
> 2.13.6

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

* Re: [PATCH 16/19] perf tools: Update tags with .cpp files
  2018-03-07 15:50 ` [PATCH 16/19] perf tools: Update tags with .cpp files Jiri Olsa
@ 2018-03-07 19:28   ` Arnaldo Carvalho de Melo
  2018-03-09  8:55   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-07 19:28 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Em Wed, Mar 07, 2018 at 04:50:17PM +0100, Jiri Olsa escreveu:
> We have some .cpp files, make ctags/cscope aware of them.

Applied
 
> Link: http://lkml.kernel.org/n/tip-37og2tumxswqeyx0htq3zu04@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/Makefile.perf | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index 4679e237a7f5..f7517e1b73f8 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -708,15 +708,15 @@ TAG_FILES= ../../include/uapi/linux/perf_event.h
>  
>  TAGS:
>  	$(QUIET_GEN)$(RM) TAGS; \
> -	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs etags -a $(TAG_FILES)
> +	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs etags -a $(TAG_FILES)
>  
>  tags:
>  	$(QUIET_GEN)$(RM) tags; \
> -	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs ctags -a $(TAG_FILES)
> +	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs ctags -a $(TAG_FILES)
>  
>  cscope:
>  	$(QUIET_GEN)$(RM) cscope*; \
> -	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs cscope -b $(TAG_FILES)
> +	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs cscope -b $(TAG_FILES)
>  
>  ### Testing rules
>  
> -- 
> 2.13.6

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

* Re: [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file
  2018-03-07 15:50 ` [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file Jiri Olsa
@ 2018-03-07 19:28   ` Arnaldo Carvalho de Melo
  2018-03-09  8:54   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-07 19:28 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Em Wed, Mar 07, 2018 at 04:50:08PM +0100, Jiri Olsa escreveu:
> Adding MEM_TOPOLOGY feature to perf data file,
> that will carry physical memory map and its
> node assignments.

Good addition, applied 1-7 in this series, skipping a few after this,
processing the rest.

- Arnaldo
 
> The format of data in MEM_TOPOLOGY is as follows:
> 
>   0 - version          | for future changes
>   8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
>  16 - count            | number of nodes
> 
>  For each node we store map of physical indexes for
>  each node:
> 
>  32 - node id          | node index
>  40 - size             | size of bitmap
>  48 - bitmap           | bitmap of memory indexes that belongs to node
>                        | /sys/devices/system/node/node<NODE>/memory<INDEX>
> 
> The MEM_TOPOLOGY could be displayed with following
> report command:
> 
>   $ perf report --header-only -I
>   ...
>   # memory nodes (nr 1, block size 0x8000000):
>   #    0 [7G]: 0-23,32-69
> 
> Link: http://lkml.kernel.org/n/tip-qq7sohu774wxq154n3my037z@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/include/linux/bitmap.h |   2 +-
>  tools/perf/util/env.h        |   9 ++
>  tools/perf/util/header.c     | 305 +++++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/header.h     |   1 +
>  4 files changed, 316 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
> index ca160270fdfa..63440cc8d618 100644
> --- a/tools/include/linux/bitmap.h
> +++ b/tools/include/linux/bitmap.h
> @@ -98,7 +98,7 @@ static inline int test_and_set_bit(int nr, unsigned long *addr)
>  
>  /**
>   * bitmap_alloc - Allocate bitmap
> - * @nr: Bit to set
> + * @nbits: Number of bits
>   */
>  static inline unsigned long *bitmap_alloc(int nbits)
>  {
> diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
> index bf970f57dce0..c4ef2e523367 100644
> --- a/tools/perf/util/env.h
> +++ b/tools/perf/util/env.h
> @@ -27,6 +27,12 @@ struct numa_node {
>  	struct cpu_map	*map;
>  };
>  
> +struct memory_node {
> +	u64		 node;
> +	u64		 size;
> +	unsigned long	*set;
> +};
> +
>  struct perf_env {
>  	char			*hostname;
>  	char			*os_release;
> @@ -43,6 +49,7 @@ struct perf_env {
>  	int			nr_sibling_cores;
>  	int			nr_sibling_threads;
>  	int			nr_numa_nodes;
> +	int			nr_memory_nodes;
>  	int			nr_pmu_mappings;
>  	int			nr_groups;
>  	char			*cmdline;
> @@ -54,6 +61,8 @@ struct perf_env {
>  	struct cpu_cache_level	*caches;
>  	int			 caches_cnt;
>  	struct numa_node	*numa_nodes;
> +	struct memory_node	*memory_nodes;
> +	unsigned long long	 memory_bsize;
>  };
>  
>  extern struct perf_env perf_env;
> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
> index e0c3cad0fd8d..3a107e7ac135 100644
> --- a/tools/perf/util/header.c
> +++ b/tools/perf/util/header.c
> @@ -17,6 +17,7 @@
>  #include <sys/stat.h>
>  #include <sys/utsname.h>
>  #include <linux/time64.h>
> +#include <dirent.h>
>  
>  #include "evlist.h"
>  #include "evsel.h"
> @@ -37,6 +38,7 @@
>  #include "asm/bug.h"
>  #include "tool.h"
>  #include "time-utils.h"
> +#include "units.h"
>  
>  #include "sane_ctype.h"
>  
> @@ -132,6 +134,25 @@ int do_write(struct feat_fd *ff, const void *buf, size_t size)
>  }
>  
>  /* Return: 0 if succeded, -ERR if failed. */
> +static int do_write_bitmap(struct feat_fd *ff, unsigned long *set, u64 size)
> +{
> +	u64 *p = (u64 *) set;
> +	int i, ret;
> +
> +	ret = do_write(ff, &size, sizeof(size));
> +	if (ret < 0)
> +		return ret;
> +
> +	for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
> +		ret = do_write(ff, p + i, sizeof(*p));
> +		if (ret < 0)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +/* Return: 0 if succeded, -ERR if failed. */
>  int write_padded(struct feat_fd *ff, const void *bf,
>  		 size_t count, size_t count_aligned)
>  {
> @@ -243,6 +264,38 @@ static char *do_read_string(struct feat_fd *ff)
>  	return NULL;
>  }
>  
> +/* Return: 0 if succeded, -ERR if failed. */
> +static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize)
> +{
> +	unsigned long *set;
> +	u64 size, *p;
> +	int i, ret;
> +
> +	ret = do_read_u64(ff, &size);
> +	if (ret)
> +		return ret;
> +
> +	set = bitmap_alloc(size);
> +	if (!set)
> +		return -ENOMEM;
> +
> +	bitmap_zero(set, size);
> +
> +	p = (u64 *) set;
> +
> +	for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
> +		ret = do_read_u64(ff, p + i);
> +		if (ret < 0) {
> +			free(set);
> +			return ret;
> +		}
> +	}
> +
> +	*pset  = set;
> +	*psize = size;
> +	return 0;
> +}
> +
>  static int write_tracing_data(struct feat_fd *ff,
>  			      struct perf_evlist *evlist)
>  {
> @@ -1196,6 +1249,176 @@ static int write_sample_time(struct feat_fd *ff,
>  			sizeof(evlist->last_sample_time));
>  }
>  
> +
> +static int memory_node__read(struct memory_node *n, unsigned long index)
> +{
> +	unsigned int phys, size = 0;
> +	char path[PATH_MAX];
> +	struct dirent *ent;
> +	DIR *dir;
> +
> +#define for_each_memory(mem, dir)					\
> +	while ((ent = readdir(dir)))					\
> +		if (strcmp(ent->d_name, ".") &&				\
> +		    strcmp(ent->d_name, "..") &&			\
> +		    sscanf(ent->d_name, "memory%u", &mem) == 1)
> +
> +	scnprintf(path, PATH_MAX,
> +		  "%s/devices/system/node/node%lu",
> +		  sysfs__mountpoint(), index);
> +
> +	dir = opendir(path);
> +	if (!dir) {
> +		pr_warning("failed: cant' open memory sysfs data\n");
> +		return -1;
> +	}
> +
> +	for_each_memory(phys, dir) {
> +		size = max(phys, size);
> +	}
> +
> +	size++;
> +
> +	n->set = bitmap_alloc(size);
> +	if (!n->set) {
> +		closedir(dir);
> +		return -ENOMEM;
> +	}
> +
> +	bitmap_zero(n->set, size);
> +	n->node = index;
> +	n->size = size;
> +
> +	rewinddir(dir);
> +
> +	for_each_memory(phys, dir) {
> +		set_bit(phys, n->set);
> +	}
> +
> +	closedir(dir);
> +	return 0;
> +}
> +
> +static int memory_node__sort(const void *a, const void *b)
> +{
> +	const struct memory_node *na = a;
> +	const struct memory_node *nb = b;
> +
> +	return na->node - nb->node;
> +}
> +
> +static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp)
> +{
> +	char path[PATH_MAX];
> +	struct dirent *ent;
> +	DIR *dir;
> +	u64 cnt = 0;
> +	int ret = 0;
> +
> +	scnprintf(path, PATH_MAX, "%s/devices/system/node/",
> +		  sysfs__mountpoint());
> +
> +	dir = opendir(path);
> +	if (!dir) {
> +		pr_warning("failed: can't open node sysfs data\n");
> +		return -1;
> +	}
> +
> +	while (!ret && (ent = readdir(dir))) {
> +		unsigned int index;
> +		int r;
> +
> +		if (!strcmp(ent->d_name, ".") ||
> +		    !strcmp(ent->d_name, ".."))
> +			continue;
> +
> +		r = sscanf(ent->d_name, "node%u", &index);
> +		if (r != 1)
> +			continue;
> +
> +		if (WARN_ONCE(cnt >= size,
> +			      "failed to write MEM_TOPOLOGY, way too many nodes\n"))
> +			return -1;
> +
> +		ret = memory_node__read(&nodes[cnt++], index);
> +	}
> +
> +	*cntp = cnt;
> +	closedir(dir);
> +
> +	if (!ret)
> +		qsort(nodes, cnt, sizeof(nodes[0]), memory_node__sort);
> +
> +	return ret;
> +}
> +
> +#define MAX_MEMORY_NODES 2000
> +
> +/*
> + * The MEM_TOPOLOGY holds physical memory map for every
> + * node in system. The format of data is as follows:
> + *
> + *  0 - version          | for future changes
> + *  8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
> + * 16 - count            | number of nodes
> + *
> + * For each node we store map of physical indexes for
> + * each node:
> + *
> + * 32 - node id          | node index
> + * 40 - size             | size of bitmap
> + * 48 - bitmap           | bitmap of memory indexes that belongs to node
> + */
> +static int write_mem_topology(struct feat_fd *ff __maybe_unused,
> +			      struct perf_evlist *evlist __maybe_unused)
> +{
> +	static struct memory_node nodes[MAX_MEMORY_NODES];
> +	u64 bsize, version = 1, i, nr;
> +	int ret;
> +
> +	ret = sysfs__read_xll("devices/system/memory/block_size_bytes",
> +			      (unsigned long long *) &bsize);
> +	if (ret)
> +		return ret;
> +
> +	ret = build_mem_topology(&nodes[0], MAX_MEMORY_NODES, &nr);
> +	if (ret)
> +		return ret;
> +
> +	ret = do_write(ff, &version, sizeof(version));
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = do_write(ff, &bsize, sizeof(bsize));
> +	if (ret < 0)
> +		goto out;
> +
> +	ret = do_write(ff, &nr, sizeof(nr));
> +	if (ret < 0)
> +		goto out;
> +
> +	for (i = 0; i < nr; i++) {
> +		struct memory_node *n = &nodes[i];
> +
> +		#define _W(v)						\
> +			ret = do_write(ff, &n->v, sizeof(n->v));	\
> +			if (ret < 0)					\
> +				goto out;
> +
> +		_W(node)
> +		_W(size)
> +
> +		#undef _W
> +
> +		ret = do_write_bitmap(ff, n->set, n->size);
> +		if (ret < 0)
> +			goto out;
> +	}
> +
> +out:
> +	return ret;
> +}
> +
>  static void print_hostname(struct feat_fd *ff, FILE *fp)
>  {
>  	fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname);
> @@ -1543,6 +1766,35 @@ static void print_sample_time(struct feat_fd *ff, FILE *fp)
>  	fprintf(fp, "# sample duration : %10.3f ms\n", d);
>  }
>  
> +static void memory_node__fprintf(struct memory_node *n,
> +				 unsigned long long bsize, FILE *fp)
> +{
> +	char buf_map[100], buf_size[50];
> +	unsigned long long size;
> +
> +	size = bsize * bitmap_weight(n->set, n->size);
> +	unit_number__scnprintf(buf_size, 50, size);
> +
> +	bitmap_scnprintf(n->set, n->size, buf_map, 100);
> +	fprintf(fp, "#  %3" PRIu64 " [%s]: %s\n", n->node, buf_size, buf_map);
> +}
> +
> +static void print_mem_topology(struct feat_fd *ff, FILE *fp)
> +{
> +	struct memory_node *nodes;
> +	int i, nr;
> +
> +	nodes = ff->ph->env.memory_nodes;
> +	nr    = ff->ph->env.nr_memory_nodes;
> +
> +	fprintf(fp, "# memory nodes (nr %d, block size 0x%llx):\n",
> +		nr, ff->ph->env.memory_bsize);
> +
> +	for (i = 0; i < nr; i++) {
> +		memory_node__fprintf(&nodes[i], ff->ph->env.memory_bsize, fp);
> +	}
> +}
> +
>  static int __event_process_build_id(struct build_id_event *bev,
>  				    char *filename,
>  				    struct perf_session *session)
> @@ -2205,6 +2457,58 @@ static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
>  	return 0;
>  }
>  
> +static int process_mem_topology(struct feat_fd *ff,
> +				void *data __maybe_unused)
> +{
> +	struct memory_node *nodes;
> +	u64 version, i, nr, bsize;
> +	int ret = -1;
> +
> +	if (do_read_u64(ff, &version))
> +		return -1;
> +
> +	if (version != 1)
> +		return -1;
> +
> +	if (do_read_u64(ff, &bsize))
> +		return -1;
> +
> +	if (do_read_u64(ff, &nr))
> +		return -1;
> +
> +	nodes = zalloc(sizeof(*nodes) * nr);
> +	if (!nodes)
> +		return -1;
> +
> +	for (i = 0; i < nr; i++) {
> +		struct memory_node n;
> +
> +		#define _R(v)				\
> +			if (do_read_u64(ff, &n.v))	\
> +				goto out;		\
> +
> +		_R(node)
> +		_R(size)
> +
> +		#undef _R
> +
> +		if (do_read_bitmap(ff, &n.set, &n.size))
> +			goto out;
> +
> +		nodes[i] = n;
> +	}
> +
> +	ff->ph->env.memory_bsize    = bsize;
> +	ff->ph->env.memory_nodes    = nodes;
> +	ff->ph->env.nr_memory_nodes = nr;
> +	ret = 0;
> +
> +out:
> +	if (ret)
> +		free(nodes);
> +	return ret;
> +}
> +
>  struct feature_ops {
>  	int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
>  	void (*print)(struct feat_fd *ff, FILE *fp);
> @@ -2263,6 +2567,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
>  	FEAT_OPN(STAT,		stat,		false),
>  	FEAT_OPN(CACHE,		cache,		true),
>  	FEAT_OPR(SAMPLE_TIME,	sample_time,	false),
> +	FEAT_OPR(MEM_TOPOLOGY,	mem_topology,	true),
>  };
>  
>  struct header_print_data {
> diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
> index 942bdec6d70d..90d4577a92dc 100644
> --- a/tools/perf/util/header.h
> +++ b/tools/perf/util/header.h
> @@ -36,6 +36,7 @@ enum {
>  	HEADER_STAT,
>  	HEADER_CACHE,
>  	HEADER_SAMPLE_TIME,
> +	HEADER_MEM_TOPOLOGY,
>  	HEADER_LAST_FEATURE,
>  	HEADER_FEAT_BITS	= 256,
>  };
> -- 
> 2.13.6

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

* Re: [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output
  2018-03-07 15:50 ` [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output Jiri Olsa
@ 2018-03-07 19:30   ` Arnaldo Carvalho de Melo
  2018-03-09  8:56   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-07 19:30 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Ingo Molnar, Namhyung Kim, David Ahern, Alexander Shishkin,
	Peter Zijlstra

Em Wed, Mar 07, 2018 at 04:50:20PM +0100, Jiri Olsa escreveu:
> So we can see the output of feature compile
> in following files:

Applied 16-19

- Arnaldo

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

* Re: [PATCH 05/19] perf tools: Add refcnt into struct mem_info
  2018-03-07 18:56   ` Arnaldo Carvalho de Melo
@ 2018-03-08 10:59     ` Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-08 10:59 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Ingo Molnar, Namhyung Kim, David Ahern,
	Alexander Shishkin, Peter Zijlstra

On Wed, Mar 07, 2018 at 03:56:59PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Mar 07, 2018 at 04:50:06PM +0100, Jiri Olsa escreveu:
> > It's passed along several hists entries in --hierarchy mode,
> > so it's better we keep track of it.
> 
> I like this, but you called it...
>  
> > +
> > +struct mem_info *mem_info__aloc(void)
> > +{
> > +	struct mem_info *mi = zalloc(sizeof(*mi));
> > +
> > +	if (mi)
> > +		refcount_set(&mi->refcnt, 1);
> > +	return mi;
> 
> "aloc" with just one 'l', so I have to fix the typo, while at it I'll
> use what is used elsewhere for this operation, i.e.
> 
> struct mem_info *mem_info__new(void);

ok, thanks

jirka

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

* Re: [PATCH 08/19] perf tools: Add mem2node object
  2018-03-07 19:27   ` Arnaldo Carvalho de Melo
@ 2018-03-08 11:03     ` Jiri Olsa
  2018-03-08 12:58       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 41+ messages in thread
From: Jiri Olsa @ 2018-03-08 11:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Ingo Molnar, Namhyung Kim, David Ahern,
	Alexander Shishkin, Peter Zijlstra

On Wed, Mar 07, 2018 at 04:27:36PM -0300, Arnaldo Carvalho de Melo wrote:

SNIP

> > diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c
> > new file mode 100644
> > index 000000000000..6da8ddbb1182
> > --- /dev/null
> > +++ b/tools/perf/util/mem2node.c
> > @@ -0,0 +1,129 @@
> > +#include <errno.h>
> > +#include <inttypes.h>
> > +#include <linux/bitmap.h>
> > +#include "mem2node.h"
> > +#include "util.h"
> > +
> > +struct entry {
> > +	struct rb_node	rb_node;
> > +	u64	start;
> > +	u64	end;
> > +	u64	node;
> > +};
> 
> Hey, this name is way too generic, please rename it to something more
> descriptive

ok, will change

> 
> > +
> > +static void entry__insert(struct entry *entry, struct rb_root *root)
> > +{
> > +	struct rb_node **p = &root->rb_node;
> > +	struct rb_node *parent = NULL;
> > +	struct entry *e;
> > +
> > +	while (*p != NULL) {
> > +		parent = *p;
> > +		e = rb_entry(parent, struct entry, rb_node);
> > +
> > +		if (entry->start < e->start)
> > +			p = &(*p)->rb_left;
> > +		else
> > +			p = &(*p)->rb_right;
> > +	}
> > +
> > +	rb_link_node(&entry->rb_node, parent, p);
> > +	rb_insert_color(&entry->rb_node, root);
> > +}
> > +
> > +int mem2node__init(struct mem2node *map, struct perf_env *env)
> > +{
> > +	struct memory_node *n, *nodes = &env->memory_nodes[0];
> > +	u64 bsize = env->memory_bsize;
> > +	struct entry *entry;
> > +	int i, j = 0, max = 0;
> > +
> > +	memset(map, 0x0, sizeof(*map));
> > +	map->root = RB_ROOT;
> > +
> > +	for (i = 0; i < env->nr_memory_nodes; i++) {
> > +		n = &nodes[i];
> > +		max += bitmap_weight(n->set, n->size);
> > +	}
> > +
> > +	entry = zalloc(sizeof(*entry) * max);
> > +	if (!entry)
> > +		return -ENOMEM;
> 
> Also this is not an 'entry', but max ones, please rename this variable
> to 'entries'.

ok


SNIP

> > +
> > +			entry[j].start = start;
> > +			entry[j].end   = start + bsize;
> > +			entry[j].node  = n->node;
> > +			RB_CLEAR_NODE(&entry[j].rb_node);
> 
> The previous four line could be done via the usual:
> 
> 			krava_entry__init(&entries[j], start, bsize, n->node);

ook

> 
> > +			j++;
> > +		}
> > +	}
> > +
> > +	/* Cut unused entries, due to merging. */
> > +	entry = realloc(entry, sizeof(*entry) * j);
> > +	if (!entry)
> > +		return -ENOMEM;
> 
> 
> Humm, so you lose it when not able to cut it short? Why not:

just shortening the memory, because some entries merge together


> 
> 	nentries = realloc(entries, sizeof(entries[0) * j);
> 	if (nentries)
> 		entries = nentries;

I don't think we need nentries.. AFAIK realloc works ok over single variable

jirka

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

* Re: [PATCH 08/19] perf tools: Add mem2node object
  2018-03-08 11:03     ` Jiri Olsa
@ 2018-03-08 12:58       ` Arnaldo Carvalho de Melo
  2018-03-08 13:00         ` Arnaldo Carvalho de Melo
  2018-03-08 13:18         ` Jiri Olsa
  0 siblings, 2 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-08 12:58 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Ingo Molnar, Namhyung Kim, David Ahern,
	Alexander Shishkin, Peter Zijlstra

Em Thu, Mar 08, 2018 at 12:03:07PM +0100, Jiri Olsa escreveu:
> On Wed, Mar 07, 2018 at 04:27:36PM -0300, Arnaldo Carvalho de Melo wrote:
> 
> SNIP
> 
> > > diff --git a/tools/perf/util/mem2node.c b/tools/perf/util/mem2node.c
> > > new file mode 100644
> > > index 000000000000..6da8ddbb1182
> > > --- /dev/null
> > > +++ b/tools/perf/util/mem2node.c
> > > @@ -0,0 +1,129 @@
> > > +#include <errno.h>
> > > +#include <inttypes.h>
> > > +#include <linux/bitmap.h>
> > > +#include "mem2node.h"
> > > +#include "util.h"
> > > +
> > > +struct entry {
> > > +	struct rb_node	rb_node;
> > > +	u64	start;
> > > +	u64	end;
> > > +	u64	node;
> > > +};
> > 
> > Hey, this name is way too generic, please rename it to something more
> > descriptive
> 
> ok, will change
> 
> > 
> > > +
> > > +static void entry__insert(struct entry *entry, struct rb_root *root)
> > > +{
> > > +	struct rb_node **p = &root->rb_node;
> > > +	struct rb_node *parent = NULL;
> > > +	struct entry *e;
> > > +
> > > +	while (*p != NULL) {
> > > +		parent = *p;
> > > +		e = rb_entry(parent, struct entry, rb_node);
> > > +
> > > +		if (entry->start < e->start)
> > > +			p = &(*p)->rb_left;
> > > +		else
> > > +			p = &(*p)->rb_right;
> > > +	}
> > > +
> > > +	rb_link_node(&entry->rb_node, parent, p);
> > > +	rb_insert_color(&entry->rb_node, root);
> > > +}
> > > +
> > > +int mem2node__init(struct mem2node *map, struct perf_env *env)
> > > +{
> > > +	struct memory_node *n, *nodes = &env->memory_nodes[0];
> > > +	u64 bsize = env->memory_bsize;
> > > +	struct entry *entry;
> > > +	int i, j = 0, max = 0;
> > > +
> > > +	memset(map, 0x0, sizeof(*map));
> > > +	map->root = RB_ROOT;
> > > +
> > > +	for (i = 0; i < env->nr_memory_nodes; i++) {
> > > +		n = &nodes[i];
> > > +		max += bitmap_weight(n->set, n->size);
> > > +	}
> > > +
> > > +	entry = zalloc(sizeof(*entry) * max);
> > > +	if (!entry)
> > > +		return -ENOMEM;
> > 
> > Also this is not an 'entry', but max ones, please rename this variable
> > to 'entries'.
> 
> ok
> 
> 
> SNIP
> 
> > > +
> > > +			entry[j].start = start;
> > > +			entry[j].end   = start + bsize;
> > > +			entry[j].node  = n->node;
> > > +			RB_CLEAR_NODE(&entry[j].rb_node);
> > 
> > The previous four line could be done via the usual:
> > 
> > 			krava_entry__init(&entries[j], start, bsize, n->node);
> 
> ook
> 
> > 
> > > +			j++;
> > > +		}
> > > +	}
> > > +
> > > +	/* Cut unused entries, due to merging. */
> > > +	entry = realloc(entry, sizeof(*entry) * j);
> > > +	if (!entry)
> > > +		return -ENOMEM;
> > 
> > 
> > Humm, so you lose it when not able to cut it short? Why not:
> 
> just shortening the memory, because some entries merge together
> 
> 
> > 
> > 	nentries = realloc(entries, sizeof(entries[0) * j);
> > 	if (nentries)
> > 		entries = nentries;
> 
> I don't think we need nentries.. AFAIK realloc works ok over single variable

So:

1) you alloc entries with a max number of entries

2) you go on populating it

3) there are some left, lets shrink it:

	entries = realloc(entries, nr_entries * sizeof(entries[0]);

Here it will probably not fail, but you check it anyway, and that is
right, what happens if this returns NULL? entries gets set to NULL,
we lose the reference to the allocated memory and you return -ENOMEM,
right?

We end up leaking entries when what I'm suggesting you to do is to
not clobber entries with the return of realloc() (doing it this way most
of the time leads to bugs), but instead store it to a temp var
(nentries), and if it succeeds, then you know that you can
set nentries to entries and go ahead with your nicely shrunk block of
memory.

If it fails, then you continue with the original block of memory, that
continues to have what you just set up, etc.

Lemme look a third time to your original patch, I must be missing
something...

- Arnaldo

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

* Re: [PATCH 08/19] perf tools: Add mem2node object
  2018-03-08 12:58       ` Arnaldo Carvalho de Melo
@ 2018-03-08 13:00         ` Arnaldo Carvalho de Melo
  2018-03-08 13:18         ` Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-03-08 13:00 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Ingo Molnar, Namhyung Kim, David Ahern,
	Alexander Shishkin, Peter Zijlstra

Em Thu, Mar 08, 2018 at 09:58:49AM -0300, Arnaldo Carvalho de Melo escreveu:
> We end up leaking entries when what I'm suggesting you to do is to
> not clobber entries with the return of realloc() (doing it this way most
> of the time leads to bugs), but instead store it to a temp var
> (nentries), and if it succeeds, then you know that you can
> set nentries to entries and go ahead with your nicely shrunk block of
> memory.
 
> If it fails, then you continue with the original block of memory, that
> continues to have what you just set up, etc.
 
> Lemme look a third time to your original patch, I must be missing
> something...

I don't think I'm missing anything ;-)

- Arnaldo

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

* Re: [PATCH 08/19] perf tools: Add mem2node object
  2018-03-08 12:58       ` Arnaldo Carvalho de Melo
  2018-03-08 13:00         ` Arnaldo Carvalho de Melo
@ 2018-03-08 13:18         ` Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: Jiri Olsa @ 2018-03-08 13:18 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Ingo Molnar, Namhyung Kim, David Ahern,
	Alexander Shishkin, Peter Zijlstra

On Thu, Mar 08, 2018 at 09:58:49AM -0300, Arnaldo Carvalho de Melo wrote:

SNIP

> > I don't think we need nentries.. AFAIK realloc works ok over single variable
> 
> So:
> 
> 1) you alloc entries with a max number of entries
> 
> 2) you go on populating it
> 
> 3) there are some left, lets shrink it:
> 
> 	entries = realloc(entries, nr_entries * sizeof(entries[0]);
> 
> Here it will probably not fail, but you check it anyway, and that is
> right, what happens if this returns NULL? entries gets set to NULL,
> we lose the reference to the allocated memory and you return -ENOMEM,
> right?
> 
> We end up leaking entries when what I'm suggesting you to do is to
> not clobber entries with the return of realloc() (doing it this way most
> of the time leads to bugs), but instead store it to a temp var
> (nentries), and if it succeeds, then you know that you can
> set nentries to entries and go ahead with your nicely shrunk block of
> memory.
> 
> If it fails, then you continue with the original block of memory, that
> continues to have what you just set up, etc.

ah that ;-) ok, will fix

thanks,
jirka

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

* [tip:perf/core] perf report: Fix the output for stdio events list
  2018-03-07 15:50 ` [PATCH 01/19] perf report: Fix the output for stdio events list Jiri Olsa
@ 2018-03-09  8:51   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, peterz, jolsa, alexander.shishkin, acme, mingo, namhyung,
	linux-kernel, dsahern, eranian, hpa

Commit-ID:  8ef278bb9305e1269f236013718801fe06a183d1
Gitweb:     https://git.kernel.org/tip/8ef278bb9305e1269f236013718801fe06a183d1
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:02 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:36 -0300

perf report: Fix the output for stdio events list

Changing the output header for reporting forced groups via --groups
option on non grouped events, like:

  $ perf record -e 'cycles,instructions'
  $ perf report --stdio --group

Before:

  # Samples: 24  of event 'anon group { cycles:u, instructions:u }'

After:

  # Samples: 24  of events 'cycles:u, instructions:u'

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Fixes: ad52b8cb4886 ("perf report: Add support to display group output for non group events")
Link: http://lkml.kernel.org/r/20180307155020.32613-2-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-report.c    | 17 ++++++++++++++---
 tools/perf/ui/browsers/hists.c |  5 +++--
 tools/perf/util/evsel.c        | 20 ++++++++++++++++----
 tools/perf/util/evsel.h        |  1 +
 4 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1eedb1815c4c..c3603d4c0c57 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -400,8 +400,10 @@ static size_t hists__fprintf_nr_sample_events(struct hists *hists, struct report
 
 	nr_samples = convert_unit(nr_samples, &unit);
 	ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
-	if (evname != NULL)
-		ret += fprintf(fp, " of event '%s'", evname);
+	if (evname != NULL) {
+		ret += fprintf(fp, " of event%s '%s'",
+			       evsel->nr_members > 1 ? "s" : "", evname);
+	}
 
 	if (rep->time_str)
 		ret += fprintf(fp, " (time slices: %s)", rep->time_str);
@@ -1175,8 +1177,17 @@ repeat:
 	has_br_stack = perf_header__has_feat(&session->header,
 					     HEADER_BRANCH_STACK);
 
-	if (group_set && !session->evlist->nr_groups)
+	/*
+	 * Events in data file are not collect in groups, but we still want
+	 * the group display. Set the artificial group and set the leader's
+	 * forced_leader flag to notify the display code.
+	 */
+	if (group_set && !session->evlist->nr_groups) {
+		struct perf_evsel *leader = perf_evlist__first(session->evlist);
+
 		perf_evlist__set_leader(session->evlist);
+		leader->forced_leader = true;
+	}
 
 	if (itrace_synth_opts.last_branch)
 		has_br_stack = true;
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index de2bde232cb3..8b4e82548f8e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -2261,8 +2261,9 @@ static int perf_evsel_browser_title(struct hist_browser *browser,
 
 	nr_samples = convert_unit(nr_samples, &unit);
 	printed = scnprintf(bf, size,
-			   "Samples: %lu%c of event '%s',%s%sEvent count (approx.): %" PRIu64,
-			   nr_samples, unit, ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
+			   "Samples: %lu%c of event%s '%s',%s%sEvent count (approx.): %" PRIu64,
+			   nr_samples, unit, evsel->nr_members > 1 ? "s" : "",
+			   ev_name, sample_freq_str, enable_ref ? ref : " ", nr_events);
 
 
 	if (hists->uid_filter_str)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e937894654b2..1ac8d9236efd 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -622,22 +622,34 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel)
 	return evsel->group_name ?: "anon group";
 }
 
+/*
+ * Returns the group details for the specified leader,
+ * with following rules.
+ *
+ *  For record -e '{cycles,instructions}'
+ *    'anon group { cycles:u, instructions:u }'
+ *
+ *  For record -e 'cycles,instructions' and report --group
+ *    'cycles:u, instructions:u'
+ */
 int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
 {
-	int ret;
+	int ret = 0;
 	struct perf_evsel *pos;
 	const char *group_name = perf_evsel__group_name(evsel);
 
-	ret = scnprintf(buf, size, "%s", group_name);
+	if (!evsel->forced_leader)
+		ret = scnprintf(buf, size, "%s { ", group_name);
 
-	ret += scnprintf(buf + ret, size - ret, " { %s",
+	ret += scnprintf(buf + ret, size - ret, "%s",
 			 perf_evsel__name(evsel));
 
 	for_each_group_member(pos, evsel)
 		ret += scnprintf(buf + ret, size - ret, ", %s",
 				 perf_evsel__name(pos));
 
-	ret += scnprintf(buf + ret, size - ret, " }");
+	if (!evsel->forced_leader)
+		ret += scnprintf(buf + ret, size - ret, " }");
 
 	return ret;
 }
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 55ae1cda7396..d3ee3af618ef 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -125,6 +125,7 @@ struct perf_evsel {
 	bool			per_pkg;
 	bool			precise_max;
 	bool			ignore_missing_thread;
+	bool			forced_leader;
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;

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

* [tip:perf/core] perf report: Display perf.data header info
  2018-03-07 15:50 ` [PATCH 02/19] perf report: Display perf.data header info Jiri Olsa
@ 2018-03-09  8:52   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:52 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jolsa, linux-kernel, dsahern, peterz, namhyung,
	alexander.shishkin, hpa, mingo, acme, tglx

Commit-ID:  e971a5a8399a5e84164239a5c2d59b8a51314241
Gitweb:     https://git.kernel.org/tip/e971a5a8399a5e84164239a5c2d59b8a51314241
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:03 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:41 -0300

perf report: Display perf.data header info

Display more header info from perf.data file, following values:

  $ perf report -i perf.data --header-only
  ...
  # header version : 1
  # data offset    : 424
  # data size      : 3364280
  # feat offset    : 3364704

It's handy for debuging.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-3-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/header.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a326e0d8b5b6..e0c3cad0fd8d 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2318,7 +2318,12 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
 	if (ret == -1)
 		return -1;
 
-	fprintf(fp, "# captured on: %s", ctime(&st.st_ctime));
+	fprintf(fp, "# captured on    : %s", ctime(&st.st_ctime));
+
+	fprintf(fp, "# header version : %u\n", header->version);
+	fprintf(fp, "# data offset    : %" PRIu64 "\n", header->data_offset);
+	fprintf(fp, "# data size      : %" PRIu64 "\n", header->data_size);
+	fprintf(fp, "# feat offset    : %" PRIu64 "\n", header->feat_offset);
 
 	perf_header__process_sections(header, fd, &hd,
 				      perf_file_section__fprintf_info);

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

* [tip:perf/core] perf record: Move machine variable down the function
  2018-03-07 15:50 ` [PATCH 03/19] perf record: Move machine variable down the function Jiri Olsa
@ 2018-03-09  8:52   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:52 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, tglx, hpa, peterz, dsahern, mingo, linux-kernel,
	alexander.shishkin, namhyung, jolsa

Commit-ID:  20a8a3cf90215cebd916048e51a5bfa6c3707778
Gitweb:     https://git.kernel.org/tip/20a8a3cf90215cebd916048e51a5bfa6c3707778
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:04 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:42 -0300

perf record: Move machine variable down the function

It's used far more down to be declared on the top of the __cmd_record.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-4-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 753ffcecf254..31d4d70e2f6a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -854,7 +854,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	int status = 0;
 	unsigned long waking = 0;
 	const bool forks = argc > 0;
-	struct machine *machine;
 	struct perf_tool *tool = &rec->tool;
 	struct record_opts *opts = &rec->opts;
 	struct perf_data *data = &rec->data;
@@ -959,8 +958,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 		goto out_child;
 	}
 
-	machine = &session->machines.host;
-
 	err = record__synthesize(rec, false);
 	if (err < 0)
 		goto out_child;
@@ -988,6 +985,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	 * Let the child rip
 	 */
 	if (forks) {
+		struct machine *machine = &session->machines.host;
 		union perf_event *event;
 		pid_t tgid;
 

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

* [tip:perf/core] perf record: Remove progname from struct record
  2018-03-07 15:50 ` [PATCH 04/19] perf record: Remove progname from struct record Jiri Olsa
@ 2018-03-09  8:53   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:53 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, dsahern, peterz, alexander.shishkin, tglx,
	namhyung, mingo, hpa, jolsa

Commit-ID:  915b4e27f1d32b3c7de4874ac1e3fe1f801151ca
Gitweb:     https://git.kernel.org/tip/915b4e27f1d32b3c7de4874ac1e3fe1f801151ca
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:05 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:43 -0300

perf record: Remove progname from struct record

It's no longer used.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-5-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 31d4d70e2f6a..b81494587120 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -71,7 +71,6 @@ struct record {
 	struct auxtrace_record	*itr;
 	struct perf_evlist	*evlist;
 	struct perf_session	*session;
-	const char		*progname;
 	int			realtime_prio;
 	bool			no_buildid;
 	bool			no_buildid_set;
@@ -861,8 +860,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
 	bool disabled = false, draining = false;
 	int fd;
 
-	rec->progname = argv[0];
-
 	atexit(record__sig_exit);
 	signal(SIGCHLD, sig_handler);
 	signal(SIGINT, sig_handler);

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

* [tip:perf/core] perf tools: Add refcnt into struct mem_info
  2018-03-07 15:50 ` [PATCH 05/19] perf tools: Add refcnt into struct mem_info Jiri Olsa
  2018-03-07 18:56   ` Arnaldo Carvalho de Melo
@ 2018-03-09  8:53   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:53 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, peterz, tglx, jolsa, alexander.shishkin, hpa, acme,
	namhyung, mingo, dsahern

Commit-ID:  9f87498f1cb72958c6f8725eb93d2f7ef81fa11e
Gitweb:     https://git.kernel.org/tip/9f87498f1cb72958c6f8725eb93d2f7ef81fa11e
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:06 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:44 -0300

perf tools: Add refcnt into struct mem_info

It's passed along several hists entries in --hierarchy mode, so it's
better we keep track of it.

The current fail I see is that it gets removed in hierarchy --mem-mode
mode, where it's shared in the different hierarchies, but removed from
the template hist entry, so the report crashes.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-6-jolsa@kernel.org
[ Rename mem_info__aloc() to mem_info__new(), to fix the typo and use the convention for constructors ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/hist.c    |  4 ++--
 tools/perf/util/machine.c |  2 +-
 tools/perf/util/symbol.c  | 22 ++++++++++++++++++++++
 tools/perf/util/symbol.h  | 19 ++++++++++++++++---
 4 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 44a8456cea10..7d968892ee39 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -536,7 +536,7 @@ static struct hist_entry *hists__findnew_entry(struct hists *hists,
 			 * This mem info was allocated from sample__resolve_mem
 			 * and will not be used anymore.
 			 */
-			zfree(&entry->mem_info);
+			mem_info__zput(entry->mem_info);
 
 			/* If the map of an existing hist_entry has
 			 * become out-of-date due to an exec() or
@@ -1139,7 +1139,7 @@ void hist_entry__delete(struct hist_entry *he)
 	if (he->mem_info) {
 		map__zput(he->mem_info->iaddr.map);
 		map__zput(he->mem_info->daddr.map);
-		zfree(&he->mem_info);
+		mem_info__zput(he->mem_info);
 	}
 
 	zfree(&he->stat_acc);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 12b7427444a3..43fbbee409ec 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1697,7 +1697,7 @@ static void ip__resolve_data(struct thread *thread,
 struct mem_info *sample__resolve_mem(struct perf_sample *sample,
 				     struct addr_location *al)
 {
-	struct mem_info *mi = zalloc(sizeof(*mi));
+	struct mem_info *mi = mem_info__new();
 
 	if (!mi)
 		return NULL;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index a1a312d99f30..62b2dd2253eb 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -2221,3 +2221,25 @@ int symbol__config_symfs(const struct option *opt __maybe_unused,
 	free(bf);
 	return 0;
 }
+
+struct mem_info *mem_info__get(struct mem_info *mi)
+{
+	if (mi)
+		refcount_inc(&mi->refcnt);
+	return mi;
+}
+
+void mem_info__put(struct mem_info *mi)
+{
+	if (mi && refcount_dec_and_test(&mi->refcnt))
+		free(mi);
+}
+
+struct mem_info *mem_info__new(void)
+{
+	struct mem_info *mi = zalloc(sizeof(*mi));
+
+	if (mi)
+		refcount_set(&mi->refcnt, 1);
+	return mi;
+}
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 0563f33c1eb3..70c16741f50a 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -200,9 +200,10 @@ struct branch_info {
 };
 
 struct mem_info {
-	struct addr_map_symbol iaddr;
-	struct addr_map_symbol daddr;
-	union perf_mem_data_src data_src;
+	struct addr_map_symbol	iaddr;
+	struct addr_map_symbol	daddr;
+	union perf_mem_data_src	data_src;
+	refcount_t		refcnt;
 };
 
 struct addr_location {
@@ -389,4 +390,16 @@ int sdt_notes__get_count(struct list_head *start);
 #define SDT_NOTE_NAME "stapsdt"
 #define NR_ADDR 3
 
+struct mem_info *mem_info__new(void);
+struct mem_info *mem_info__get(struct mem_info *mi);
+void   mem_info__put(struct mem_info *mi);
+
+static inline void __mem_info__zput(struct mem_info **mi)
+{
+	mem_info__put(*mi);
+	*mi = NULL;
+}
+
+#define mem_info__zput(mi) __mem_info__zput(&mi)
+
 #endif /* __PERF_SYMBOL */

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

* [tip:perf/core] perf c2c: Use mem_info refcnt logic
  2018-03-07 15:50 ` [PATCH 06/19] perf c2c: Use mem_info refcnt logic Jiri Olsa
@ 2018-03-09  8:54   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:54 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: alexander.shishkin, jolsa, linux-kernel, tglx, dsahern, mingo,
	namhyung, hpa, peterz, acme

Commit-ID:  5cedb413a63d452356aa634e0d4ffcc24f7dbcb5
Gitweb:     https://git.kernel.org/tip/5cedb413a63d452356aa634e0d4ffcc24f7dbcb5
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:07 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:45 -0300

perf c2c: Use mem_info refcnt logic

Switch to refcnt logic instead of duplicating mem_info objects. No
functional change, just saving some memory.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-7-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-c2c.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index 539c3d460158..98d243fa0c06 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -237,9 +237,12 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 	if (mi == NULL)
 		return -ENOMEM;
 
-	mi_dup = memdup(mi, sizeof(*mi));
-	if (!mi_dup)
-		goto free_mi;
+	/*
+	 * The mi object is released in hists__add_entry_ops,
+	 * if it gets sorted out into existing data, so we need
+	 * to take the copy now.
+	 */
+	mi_dup = mem_info__get(mi);
 
 	c2c_decode_stats(&stats, mi);
 
@@ -247,7 +250,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 				  &al, NULL, NULL, mi,
 				  sample, true);
 	if (he == NULL)
-		goto free_mi_dup;
+		goto free_mi;
 
 	c2c_he = container_of(he, struct c2c_hist_entry, he);
 	c2c_add_stats(&c2c_he->stats, &stats);
@@ -272,19 +275,15 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 
 		mi = mi_dup;
 
-		mi_dup = memdup(mi, sizeof(*mi));
-		if (!mi_dup)
-			goto free_mi;
-
 		c2c_hists = he__get_c2c_hists(he, c2c.cl_sort, 2);
 		if (!c2c_hists)
-			goto free_mi_dup;
+			goto free_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;
+			goto free_mi;
 
 		c2c_he = container_of(he, struct c2c_hist_entry, he);
 		c2c_add_stats(&c2c_he->stats, &stats);
@@ -303,10 +302,9 @@ out:
 	addr_location__put(&al);
 	return ret;
 
-free_mi_dup:
-	free(mi_dup);
 free_mi:
-	free(mi);
+	mem_info__put(mi_dup);
+	mem_info__put(mi);
 	ret = -ENOMEM;
 	goto out;
 }

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

* [tip:perf/core] perf tools: Add MEM_TOPOLOGY feature to perf data file
  2018-03-07 15:50 ` [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file Jiri Olsa
  2018-03-07 19:28   ` Arnaldo Carvalho de Melo
@ 2018-03-09  8:54   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:54 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: namhyung, tglx, hpa, linux-kernel, jolsa, peterz, acme,
	alexander.shishkin, mingo, dsahern

Commit-ID:  e2091cedd51bf5306bcd5dd498d2977abfe20e88
Gitweb:     https://git.kernel.org/tip/e2091cedd51bf5306bcd5dd498d2977abfe20e88
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:08 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:46 -0300

perf tools: Add MEM_TOPOLOGY feature to perf data file

Adding MEM_TOPOLOGY feature to perf data file,
that will carry physical memory map and its
node assignments.

The format of data in MEM_TOPOLOGY is as follows:

  0 - version          | for future changes
  8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
 16 - count            | number of nodes

 For each node we store map of physical indexes for
 each node:

 32 - node id          | node index
 40 - size             | size of bitmap
 48 - bitmap           | bitmap of memory indexes that belongs to node
                       | /sys/devices/system/node/node<NODE>/memory<INDEX>

The MEM_TOPOLOGY could be displayed with following
report command:

  $ perf report --header-only -I
  ...
  # memory nodes (nr 1, block size 0x8000000):
  #    0 [7G]: 0-23,32-69

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-8-jolsa@kernel.org
[ Rename 'index' to 'idx', as this breaks the build in rhel5, 6 and other systems where this is used by glibc headers ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/include/linux/bitmap.h |   2 +-
 tools/perf/util/env.h        |   9 ++
 tools/perf/util/header.c     | 305 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/header.h     |   1 +
 4 files changed, 316 insertions(+), 1 deletion(-)

diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h
index ca160270fdfa..63440cc8d618 100644
--- a/tools/include/linux/bitmap.h
+++ b/tools/include/linux/bitmap.h
@@ -98,7 +98,7 @@ static inline int test_and_set_bit(int nr, unsigned long *addr)
 
 /**
  * bitmap_alloc - Allocate bitmap
- * @nr: Bit to set
+ * @nbits: Number of bits
  */
 static inline unsigned long *bitmap_alloc(int nbits)
 {
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index bf970f57dce0..c4ef2e523367 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -27,6 +27,12 @@ struct numa_node {
 	struct cpu_map	*map;
 };
 
+struct memory_node {
+	u64		 node;
+	u64		 size;
+	unsigned long	*set;
+};
+
 struct perf_env {
 	char			*hostname;
 	char			*os_release;
@@ -43,6 +49,7 @@ struct perf_env {
 	int			nr_sibling_cores;
 	int			nr_sibling_threads;
 	int			nr_numa_nodes;
+	int			nr_memory_nodes;
 	int			nr_pmu_mappings;
 	int			nr_groups;
 	char			*cmdline;
@@ -54,6 +61,8 @@ struct perf_env {
 	struct cpu_cache_level	*caches;
 	int			 caches_cnt;
 	struct numa_node	*numa_nodes;
+	struct memory_node	*memory_nodes;
+	unsigned long long	 memory_bsize;
 };
 
 extern struct perf_env perf_env;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e0c3cad0fd8d..e14b3f7c7212 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -17,6 +17,7 @@
 #include <sys/stat.h>
 #include <sys/utsname.h>
 #include <linux/time64.h>
+#include <dirent.h>
 
 #include "evlist.h"
 #include "evsel.h"
@@ -37,6 +38,7 @@
 #include "asm/bug.h"
 #include "tool.h"
 #include "time-utils.h"
+#include "units.h"
 
 #include "sane_ctype.h"
 
@@ -131,6 +133,25 @@ int do_write(struct feat_fd *ff, const void *buf, size_t size)
 	return __do_write_buf(ff, buf, size);
 }
 
+/* Return: 0 if succeded, -ERR if failed. */
+static int do_write_bitmap(struct feat_fd *ff, unsigned long *set, u64 size)
+{
+	u64 *p = (u64 *) set;
+	int i, ret;
+
+	ret = do_write(ff, &size, sizeof(size));
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
+		ret = do_write(ff, p + i, sizeof(*p));
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 /* Return: 0 if succeded, -ERR if failed. */
 int write_padded(struct feat_fd *ff, const void *bf,
 		 size_t count, size_t count_aligned)
@@ -243,6 +264,38 @@ static char *do_read_string(struct feat_fd *ff)
 	return NULL;
 }
 
+/* Return: 0 if succeded, -ERR if failed. */
+static int do_read_bitmap(struct feat_fd *ff, unsigned long **pset, u64 *psize)
+{
+	unsigned long *set;
+	u64 size, *p;
+	int i, ret;
+
+	ret = do_read_u64(ff, &size);
+	if (ret)
+		return ret;
+
+	set = bitmap_alloc(size);
+	if (!set)
+		return -ENOMEM;
+
+	bitmap_zero(set, size);
+
+	p = (u64 *) set;
+
+	for (i = 0; (u64) i < BITS_TO_U64(size); i++) {
+		ret = do_read_u64(ff, p + i);
+		if (ret < 0) {
+			free(set);
+			return ret;
+		}
+	}
+
+	*pset  = set;
+	*psize = size;
+	return 0;
+}
+
 static int write_tracing_data(struct feat_fd *ff,
 			      struct perf_evlist *evlist)
 {
@@ -1196,6 +1249,176 @@ static int write_sample_time(struct feat_fd *ff,
 			sizeof(evlist->last_sample_time));
 }
 
+
+static int memory_node__read(struct memory_node *n, unsigned long idx)
+{
+	unsigned int phys, size = 0;
+	char path[PATH_MAX];
+	struct dirent *ent;
+	DIR *dir;
+
+#define for_each_memory(mem, dir)					\
+	while ((ent = readdir(dir)))					\
+		if (strcmp(ent->d_name, ".") &&				\
+		    strcmp(ent->d_name, "..") &&			\
+		    sscanf(ent->d_name, "memory%u", &mem) == 1)
+
+	scnprintf(path, PATH_MAX,
+		  "%s/devices/system/node/node%lu",
+		  sysfs__mountpoint(), idx);
+
+	dir = opendir(path);
+	if (!dir) {
+		pr_warning("failed: cant' open memory sysfs data\n");
+		return -1;
+	}
+
+	for_each_memory(phys, dir) {
+		size = max(phys, size);
+	}
+
+	size++;
+
+	n->set = bitmap_alloc(size);
+	if (!n->set) {
+		closedir(dir);
+		return -ENOMEM;
+	}
+
+	bitmap_zero(n->set, size);
+	n->node = idx;
+	n->size = size;
+
+	rewinddir(dir);
+
+	for_each_memory(phys, dir) {
+		set_bit(phys, n->set);
+	}
+
+	closedir(dir);
+	return 0;
+}
+
+static int memory_node__sort(const void *a, const void *b)
+{
+	const struct memory_node *na = a;
+	const struct memory_node *nb = b;
+
+	return na->node - nb->node;
+}
+
+static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp)
+{
+	char path[PATH_MAX];
+	struct dirent *ent;
+	DIR *dir;
+	u64 cnt = 0;
+	int ret = 0;
+
+	scnprintf(path, PATH_MAX, "%s/devices/system/node/",
+		  sysfs__mountpoint());
+
+	dir = opendir(path);
+	if (!dir) {
+		pr_warning("failed: can't open node sysfs data\n");
+		return -1;
+	}
+
+	while (!ret && (ent = readdir(dir))) {
+		unsigned int idx;
+		int r;
+
+		if (!strcmp(ent->d_name, ".") ||
+		    !strcmp(ent->d_name, ".."))
+			continue;
+
+		r = sscanf(ent->d_name, "node%u", &idx);
+		if (r != 1)
+			continue;
+
+		if (WARN_ONCE(cnt >= size,
+			      "failed to write MEM_TOPOLOGY, way too many nodes\n"))
+			return -1;
+
+		ret = memory_node__read(&nodes[cnt++], idx);
+	}
+
+	*cntp = cnt;
+	closedir(dir);
+
+	if (!ret)
+		qsort(nodes, cnt, sizeof(nodes[0]), memory_node__sort);
+
+	return ret;
+}
+
+#define MAX_MEMORY_NODES 2000
+
+/*
+ * The MEM_TOPOLOGY holds physical memory map for every
+ * node in system. The format of data is as follows:
+ *
+ *  0 - version          | for future changes
+ *  8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
+ * 16 - count            | number of nodes
+ *
+ * For each node we store map of physical indexes for
+ * each node:
+ *
+ * 32 - node id          | node index
+ * 40 - size             | size of bitmap
+ * 48 - bitmap           | bitmap of memory indexes that belongs to node
+ */
+static int write_mem_topology(struct feat_fd *ff __maybe_unused,
+			      struct perf_evlist *evlist __maybe_unused)
+{
+	static struct memory_node nodes[MAX_MEMORY_NODES];
+	u64 bsize, version = 1, i, nr;
+	int ret;
+
+	ret = sysfs__read_xll("devices/system/memory/block_size_bytes",
+			      (unsigned long long *) &bsize);
+	if (ret)
+		return ret;
+
+	ret = build_mem_topology(&nodes[0], MAX_MEMORY_NODES, &nr);
+	if (ret)
+		return ret;
+
+	ret = do_write(ff, &version, sizeof(version));
+	if (ret < 0)
+		goto out;
+
+	ret = do_write(ff, &bsize, sizeof(bsize));
+	if (ret < 0)
+		goto out;
+
+	ret = do_write(ff, &nr, sizeof(nr));
+	if (ret < 0)
+		goto out;
+
+	for (i = 0; i < nr; i++) {
+		struct memory_node *n = &nodes[i];
+
+		#define _W(v)						\
+			ret = do_write(ff, &n->v, sizeof(n->v));	\
+			if (ret < 0)					\
+				goto out;
+
+		_W(node)
+		_W(size)
+
+		#undef _W
+
+		ret = do_write_bitmap(ff, n->set, n->size);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	return ret;
+}
+
 static void print_hostname(struct feat_fd *ff, FILE *fp)
 {
 	fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname);
@@ -1543,6 +1766,35 @@ static void print_sample_time(struct feat_fd *ff, FILE *fp)
 	fprintf(fp, "# sample duration : %10.3f ms\n", d);
 }
 
+static void memory_node__fprintf(struct memory_node *n,
+				 unsigned long long bsize, FILE *fp)
+{
+	char buf_map[100], buf_size[50];
+	unsigned long long size;
+
+	size = bsize * bitmap_weight(n->set, n->size);
+	unit_number__scnprintf(buf_size, 50, size);
+
+	bitmap_scnprintf(n->set, n->size, buf_map, 100);
+	fprintf(fp, "#  %3" PRIu64 " [%s]: %s\n", n->node, buf_size, buf_map);
+}
+
+static void print_mem_topology(struct feat_fd *ff, FILE *fp)
+{
+	struct memory_node *nodes;
+	int i, nr;
+
+	nodes = ff->ph->env.memory_nodes;
+	nr    = ff->ph->env.nr_memory_nodes;
+
+	fprintf(fp, "# memory nodes (nr %d, block size 0x%llx):\n",
+		nr, ff->ph->env.memory_bsize);
+
+	for (i = 0; i < nr; i++) {
+		memory_node__fprintf(&nodes[i], ff->ph->env.memory_bsize, fp);
+	}
+}
+
 static int __event_process_build_id(struct build_id_event *bev,
 				    char *filename,
 				    struct perf_session *session)
@@ -2205,6 +2457,58 @@ static int process_sample_time(struct feat_fd *ff, void *data __maybe_unused)
 	return 0;
 }
 
+static int process_mem_topology(struct feat_fd *ff,
+				void *data __maybe_unused)
+{
+	struct memory_node *nodes;
+	u64 version, i, nr, bsize;
+	int ret = -1;
+
+	if (do_read_u64(ff, &version))
+		return -1;
+
+	if (version != 1)
+		return -1;
+
+	if (do_read_u64(ff, &bsize))
+		return -1;
+
+	if (do_read_u64(ff, &nr))
+		return -1;
+
+	nodes = zalloc(sizeof(*nodes) * nr);
+	if (!nodes)
+		return -1;
+
+	for (i = 0; i < nr; i++) {
+		struct memory_node n;
+
+		#define _R(v)				\
+			if (do_read_u64(ff, &n.v))	\
+				goto out;		\
+
+		_R(node)
+		_R(size)
+
+		#undef _R
+
+		if (do_read_bitmap(ff, &n.set, &n.size))
+			goto out;
+
+		nodes[i] = n;
+	}
+
+	ff->ph->env.memory_bsize    = bsize;
+	ff->ph->env.memory_nodes    = nodes;
+	ff->ph->env.nr_memory_nodes = nr;
+	ret = 0;
+
+out:
+	if (ret)
+		free(nodes);
+	return ret;
+}
+
 struct feature_ops {
 	int (*write)(struct feat_fd *ff, struct perf_evlist *evlist);
 	void (*print)(struct feat_fd *ff, FILE *fp);
@@ -2263,6 +2567,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
 	FEAT_OPN(STAT,		stat,		false),
 	FEAT_OPN(CACHE,		cache,		true),
 	FEAT_OPR(SAMPLE_TIME,	sample_time,	false),
+	FEAT_OPR(MEM_TOPOLOGY,	mem_topology,	true),
 };
 
 struct header_print_data {
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 942bdec6d70d..90d4577a92dc 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -36,6 +36,7 @@ enum {
 	HEADER_STAT,
 	HEADER_CACHE,
 	HEADER_SAMPLE_TIME,
+	HEADER_MEM_TOPOLOGY,
 	HEADER_LAST_FEATURE,
 	HEADER_FEAT_BITS	= 256,
 };

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

* [tip:perf/core] perf tools: Update tags with .cpp files
  2018-03-07 15:50 ` [PATCH 16/19] perf tools: Update tags with .cpp files Jiri Olsa
  2018-03-07 19:28   ` Arnaldo Carvalho de Melo
@ 2018-03-09  8:55   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:55 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, acme, hpa, mingo, peterz, dsahern, namhyung, linux-kernel,
	jolsa, alexander.shishkin

Commit-ID:  ed3956293f2913047c622c238b5bf7ff4fe250bf
Gitweb:     https://git.kernel.org/tip/ed3956293f2913047c622c238b5bf7ff4fe250bf
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:17 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:47 -0300

perf tools: Update tags with .cpp files

We have some .cpp files, make ctags/cscope aware of them.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-17-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Makefile.perf | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 4679e237a7f5..f7517e1b73f8 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -708,15 +708,15 @@ TAG_FILES= ../../include/uapi/linux/perf_event.h
 
 TAGS:
 	$(QUIET_GEN)$(RM) TAGS; \
-	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs etags -a $(TAG_FILES)
+	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs etags -a $(TAG_FILES)
 
 tags:
 	$(QUIET_GEN)$(RM) tags; \
-	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs ctags -a $(TAG_FILES)
+	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs ctags -a $(TAG_FILES)
 
 cscope:
 	$(QUIET_GEN)$(RM) cscope*; \
-	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print | xargs cscope -b $(TAG_FILES)
+	$(FIND) $(TAG_FOLDERS) -name '*.[hcS]' -print -o -name '*.cpp' -print | xargs cscope -b $(TAG_FILES)
 
 ### Testing rules
 

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

* [tip:perf/core] perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA
  2018-03-07 15:50 ` [PATCH 17/19] perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA Jiri Olsa
@ 2018-03-09  8:55   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:55 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, linux-kernel, jolsa, namhyung, hpa, acme,
	alexander.shishkin, mingo, dsahern, tglx

Commit-ID:  bd476684584ecc3e269167d595c6dd5375011ca0
Gitweb:     https://git.kernel.org/tip/bd476684584ecc3e269167d595c6dd5375011ca0
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:18 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:48 -0300

perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA

So we can see the status when we build perf, like:

  $ make LIBCLANGLLVM=1 VF=1
  ...                           cxx: [ on  ]
  ...                          llvm: [ on  ]
  ...                  llvm-version: [ on  ]
  ...                         clang: [ on  ]

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-18-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/build/Makefile.feature | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index c378f003b007..5b6dda3b1ca8 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -82,7 +82,11 @@ FEATURE_TESTS_EXTRA :=                  \
          liberty-z                      \
          libunwind-debug-frame          \
          libunwind-debug-frame-arm      \
-         libunwind-debug-frame-aarch64
+         libunwind-debug-frame-aarch64  \
+         cxx                            \
+         llvm                           \
+         llvm-version                   \
+         clang
 
 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
 

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

* [tip:perf/core] perf build: Add llvm/clang make targets to FILES
  2018-03-07 15:50 ` [PATCH 18/19] perf build: Add llvm/clang make targets to FILES Jiri Olsa
@ 2018-03-09  8:56   ` tip-bot for Jiri Olsa
  0 siblings, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:56 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: alexander.shishkin, hpa, mingo, dsahern, namhyung, jolsa, tglx,
	peterz, acme, linux-kernel

Commit-ID:  36f9dc33b9128b85e096f6fff83e05d49448b28e
Gitweb:     https://git.kernel.org/tip/36f9dc33b9128b85e096f6fff83e05d49448b28e
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:19 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:49 -0300

perf build: Add llvm/clang make targets to FILES

So they can follow the OUTPUT variable setup as the rest of the
features.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-19-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/build/feature/Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 0a490cb15149..f8ad640ffe5d 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -54,7 +54,10 @@ FILES=                                          \
          test-jvmti.bin				\
          test-sched_getcpu.bin			\
          test-setns.bin				\
-         test-libopencsd.bin
+         test-libopencsd.bin			\
+         test-clang.bin				\
+         test-llvm.bin				\
+         test-llvm-version.bin
 
 FILES := $(addprefix $(OUTPUT),$(FILES))
 

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

* [tip:perf/core] perf build: Force llvm/clang test compile output to .make.output
  2018-03-07 15:50 ` [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output Jiri Olsa
  2018-03-07 19:30   ` Arnaldo Carvalho de Melo
@ 2018-03-09  8:56   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 41+ messages in thread
From: tip-bot for Jiri Olsa @ 2018-03-09  8:56 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, peterz, mingo, jolsa, dsahern, alexander.shishkin, acme,
	hpa, linux-kernel, namhyung

Commit-ID:  5fb3d8b7b50d2101b0c15d2e90264deb7a01c2d8
Gitweb:     https://git.kernel.org/tip/5fb3d8b7b50d2101b0c15d2e90264deb7a01c2d8
Author:     Jiri Olsa <jolsa@kernel.org>
AuthorDate: Wed, 7 Mar 2018 16:50:20 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Thu, 8 Mar 2018 11:30:50 -0300

perf build: Force llvm/clang test compile output to .make.output

So we can see the output of feature compile in following files:

  tools/build/feature/test-llvm.make.output
  tools/build/feature/test-llvm-version.make.output
  tools/build/feature/test-clang.make.output

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20180307155020.32613-20-jolsa@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/build/feature/Makefile | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index f8ad640ffe5d..dac9563b5470 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -260,11 +260,13 @@ $(OUTPUT)test-llvm.bin:
 		-I$(shell $(LLVM_CONFIG) --includedir) 		\
 		-L$(shell $(LLVM_CONFIG) --libdir)		\
 		$(shell $(LLVM_CONFIG) --libs Core BPF)		\
-		$(shell $(LLVM_CONFIG) --system-libs)
+		$(shell $(LLVM_CONFIG) --system-libs)		\
+		> $(@:.bin=.make.output) 2>&1
 
 $(OUTPUT)test-llvm-version.bin:
 	$(BUILDXX) -std=gnu++11 				\
-		-I$(shell $(LLVM_CONFIG) --includedir)
+		-I$(shell $(LLVM_CONFIG) --includedir)		\
+		> $(@:.bin=.make.output) 2>&1
 
 $(OUTPUT)test-clang.bin:
 	$(BUILDXX) -std=gnu++11 				\
@@ -274,7 +276,8 @@ $(OUTPUT)test-clang.bin:
 		  -lclangFrontend -lclangEdit -lclangLex	\
 		  -lclangAST -Wl,--end-group 			\
 		$(shell $(LLVM_CONFIG) --libs Core option)	\
-		$(shell $(LLVM_CONFIG) --system-libs)
+		$(shell $(LLVM_CONFIG) --system-libs)		\
+		> $(@:.bin=.make.output) 2>&1
 
 -include $(OUTPUT)*.d
 

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

end of thread, other threads:[~2018-03-09  8:58 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-07 15:50 [PATCH 00/19] perf tools: Assorted fixes Jiri Olsa
2018-03-07 15:50 ` [PATCH 01/19] perf report: Fix the output for stdio events list Jiri Olsa
2018-03-09  8:51   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 02/19] perf report: Display perf.data header info Jiri Olsa
2018-03-09  8:52   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 03/19] perf record: Move machine variable down the function Jiri Olsa
2018-03-09  8:52   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 04/19] perf record: Remove progname from struct record Jiri Olsa
2018-03-09  8:53   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 05/19] perf tools: Add refcnt into struct mem_info Jiri Olsa
2018-03-07 18:56   ` Arnaldo Carvalho de Melo
2018-03-08 10:59     ` Jiri Olsa
2018-03-09  8:53   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 06/19] perf c2c: Use mem_info refcnt logic Jiri Olsa
2018-03-09  8:54   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 07/19] perf tools: Add MEM_TOPOLOGY feature to perf data file Jiri Olsa
2018-03-07 19:28   ` Arnaldo Carvalho de Melo
2018-03-09  8:54   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 08/19] perf tools: Add mem2node object Jiri Olsa
2018-03-07 19:27   ` Arnaldo Carvalho de Melo
2018-03-08 11:03     ` Jiri Olsa
2018-03-08 12:58       ` Arnaldo Carvalho de Melo
2018-03-08 13:00         ` Arnaldo Carvalho de Melo
2018-03-08 13:18         ` Jiri Olsa
2018-03-07 15:50 ` [PATCH 09/19] perf tests: Add mem2node object test Jiri Olsa
2018-03-07 15:50 ` [PATCH 10/19] perf c2c record: Record physical addresses in samples Jiri Olsa
2018-03-07 15:50 ` [PATCH 11/19] perf c2c report: Make calc_width work with struct c2c_hist_entry Jiri Olsa
2018-03-07 15:50 ` [PATCH 12/19] perf c2c report: Call calc_width only for displayed entries Jiri Olsa
2018-03-07 15:50 ` [PATCH 13/19] perf c2c report: Display node for cacheline address Jiri Olsa
2018-03-07 15:50 ` [PATCH 14/19] perf c2c report: Add span header over cacheline data Jiri Olsa
2018-03-07 15:50 ` [PATCH 15/19] perf c2c report: Add cacheline address count column Jiri Olsa
2018-03-07 15:50 ` [PATCH 16/19] perf tools: Update tags with .cpp files Jiri Olsa
2018-03-07 19:28   ` Arnaldo Carvalho de Melo
2018-03-09  8:55   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 17/19] perf build: Add llvm/clang/cxx make tests into FEATURE_TESTS_EXTRA Jiri Olsa
2018-03-09  8:55   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 18/19] perf build: Add llvm/clang make targets to FILES Jiri Olsa
2018-03-09  8:56   ` [tip:perf/core] " tip-bot for Jiri Olsa
2018-03-07 15:50 ` [PATCH 19/19] perf build: Force llvm/clang test compile output to .make.output Jiri Olsa
2018-03-07 19:30   ` Arnaldo Carvalho de Melo
2018-03-09  8:56   ` [tip:perf/core] " tip-bot for 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.