Skip to contentSkip to conversation

perf tools: Various fixes

PATCH Superseded Jiri Olsa 5 participants 35 messages Jan 7, 2016 – Jan 9, 2016 perf events

lore
Share & tools
lore

Jiri Olsa

author reviewer
#0 lore raw

v2 cover perf tools: Various fixes

hi,
sending several changes together:
- leftover for the stat enable/disable changes with Adrian's patch
- fixes for issues Noel found with DWARF unwind
- asorted small fixes

v2 changes:
- store data mmaps automaticaly for dwarf unwind, not unconditionaly [Namhyung]

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

thanks,
jirka

---
Adrian Hunter (1):
perf tools: Make perf_evlist__open() open evsels with their cpus and threads (like perf record does)

Jiri Olsa (11):
perf tools: Remove perf_evlist__(enable|disable)_event functions perf tools: Use find_map function in access_dso_mem
perf tools libunwind: Check for mmaps also in MAP__VARIABLE tree perf tools libdw: Check for mmaps also in MAP__VARIABLE tree perf record: Store data mmaps for dwarf unwind
perf tools: Do not show trace command if it's not compiled in perf script: Align event name properly
perf tools: Include all tools/lib directory for tags/cscope/TAGS targets perf tools: Remove list entry from struct sort_entry
perf tools: Add overhead/overhead_children keys defaults via string perf diff: Use perf_hpp__register_sort_field interface

Namhyung Kim (1):
perf tools: Export a couple of hist functions

 tools/perf/Makefile.perf             |  2 +-
 tools/perf/arch/x86/util/intel-bts.c |  4 ++--
 tools/perf/arch/x86/util/intel-pt.c  |  4 ++--
 tools/perf/builtin-diff.c            |  2 +-
 tools/perf/builtin-record.c          |  1 +
 tools/perf/builtin-script.c          | 24 ++++++++++++++++++++++--
 tools/perf/command-list.txt          |  2 +-
 tools/perf/tests/keep-tracking.c     |  2 +-
 tools/perf/tests/switch-tracking.c   |  6 +++---
 tools/perf/ui/hist.c                 | 12 ------------
 tools/perf/util/evlist.c             | 44 +-------------------------------------------
 tools/perf/util/evlist.h             |  4 ----
 tools/perf/util/generate-cmdlist.sh  | 15 +++++++++++++++
 tools/perf/util/hist.c               | 19 ++++++++++++-------
 tools/perf/util/hist.h               |  5 +++++
 tools/perf/util/sort.c               | 39 +++++++++++++++++++++++++++++++++++++++
 tools/perf/util/sort.h               |  2 --
 tools/perf/util/unwind-libdw.c       | 10 ++++++++++
 tools/perf/util/unwind-libunwind.c   | 20 ++++++++++++++------
 19 files changed, 130 insertions(+), 87 deletions(-)
author reviewer
#1 lore raw

PATCH v2 1/13 perf tools: Remove perf_evlist__(enable|disable)_event functions

Replacing them with perf_evsel__(enable|disable).

---
 tools/perf/arch/x86/util/intel-bts.c |  4 ++--
 tools/perf/arch/x86/util/intel-pt.c  |  4 ++--
 tools/perf/tests/keep-tracking.c     |  2 +-
 tools/perf/tests/switch-tracking.c   |  6 +++---
 tools/perf/util/evlist.c             | 42 ------------------------------------
 tools/perf/util/evlist.h             |  4 ----
 6 files changed, 8 insertions(+), 54 deletions(-)
tools/perf/arch/x86/util/intel-bts.c +2 -2
index 9b94ce520917..8d8150f1cf9b 100644
@@ -327,7 +327,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr)
 
 	evlist__for_each(btsr->evlist, evsel) {
 		if (evsel->attr.type == btsr->intel_bts_pmu->type)
-			return perf_evlist__disable_event(btsr->evlist, evsel);
+			return perf_evsel__disable(evsel);
 	}
 	return -EINVAL;
 }
@@ -340,7 +340,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr)
 
 	evlist__for_each(btsr->evlist, evsel) {
 		if (evsel->attr.type == btsr->intel_bts_pmu->type)
-			return perf_evlist__enable_event(btsr->evlist, evsel);
+			return perf_evsel__enable(evsel);
 	}
 	return -EINVAL;
 }
tools/perf/arch/x86/util/intel-pt.c +2 -2
index b64d46285ebb..f05daacc9e78 100644
@@ -725,7 +725,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr)
 
 	evlist__for_each(ptr->evlist, evsel) {
 		if (evsel->attr.type == ptr->intel_pt_pmu->type)
-			return perf_evlist__disable_event(ptr->evlist, evsel);
+			return perf_evsel__disable(evsel);
 	}
 	return -EINVAL;
 }
@@ -738,7 +738,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr)
 
 	evlist__for_each(ptr->evlist, evsel) {
 		if (evsel->attr.type == ptr->intel_pt_pmu->type)
-			return perf_evlist__enable_event(ptr->evlist, evsel);
+			return perf_evsel__enable(evsel);
 	}
 	return -EINVAL;
 }
tools/perf/tests/keep-tracking.c +1 -1
index a337a6da1f39..7b27943ecfef 100644
@@ -124,7 +124,7 @@ int test__keep_tracking(int subtest __maybe_unused)
 
 	evsel = perf_evlist__last(evlist);
 
-	CHECK__(perf_evlist__disable_event(evlist, evsel));
+	CHECK__(perf_evsel__disable(evsel));
 
 	comm = "Test COMM 2";
 	CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));
tools/perf/tests/switch-tracking.c +3 -3
index dfbd8d69ce89..ebd80168d51e 100644
@@ -455,7 +455,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 
 	perf_evlist__enable(evlist);
 
-	err = perf_evlist__disable_event(evlist, cpu_clocks_evsel);
+	err = perf_evsel__disable(cpu_clocks_evsel);
 	if (err) {
 		pr_debug("perf_evlist__disable_event failed!\n");
 		goto out_err;
@@ -474,7 +474,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 		goto out_err;
 	}
 
-	err = perf_evlist__disable_event(evlist, cycles_evsel);
+	err = perf_evsel__disable(cycles_evsel);
 	if (err) {
 		pr_debug("perf_evlist__disable_event failed!\n");
 		goto out_err;
@@ -500,7 +500,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 		goto out_err;
 	}
 
-	err = perf_evlist__enable_event(evlist, cycles_evsel);
+	err = perf_evsel__enable(cycles_evsel);
 	if (err) {
 		pr_debug("perf_evlist__disable_event failed!\n");
 		goto out_err;
tools/perf/util/evlist.c +0 -42

48 lines not on this page · raw message

tools/perf/util/evlist.h +0 -4
index 139a50038097..25c6c824d870 100644
@@ -152,10 +152,6 @@ void perf_evlist__disable(struct perf_evlist *evlist);
 void perf_evlist__enable(struct perf_evlist *evlist);
 void perf_evlist__toggle_enable(struct perf_evlist *evlist);
 
-int perf_evlist__disable_event(struct perf_evlist *evlist,
-			       struct perf_evsel *evsel);
-int perf_evlist__enable_event(struct perf_evlist *evlist,
-			      struct perf_evsel *evsel);
 int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
 				  struct perf_evsel *evsel, int idx);
 
Signature · 1 line
2.4.3
#2 lore raw

[tip:perf/core] perf evlist: Remove perf_evlist__(enable|disable) _event functions

perf evlist: Remove perf_evlist__(enable|disable)_event functions
Commit-ID:  d2190a8091124f832c8862ace3a3d7d70a2506a5
Gitweb:     http://git.kernel.org/tip/d2190a8091124f832c8862ace3a3d7d70a2506a5
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:13:58 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 14:15:43 -0300

perf evlist: Remove perf_evlist__(enable|disable)_event functions

Replacing them with perf_evsel__(enable|disable).

---
 tools/perf/arch/x86/util/intel-bts.c |  4 ++--
 tools/perf/arch/x86/util/intel-pt.c  |  4 ++--
 tools/perf/tests/keep-tracking.c     |  2 +-
 tools/perf/tests/switch-tracking.c   |  6 +++---
 tools/perf/util/evlist.c             | 42 ------------------------------------
 tools/perf/util/evlist.h             |  4 ----
 6 files changed, 8 insertions(+), 54 deletions(-)
tools/perf/arch/x86/util/intel-bts.c +2 -2
index 9b94ce5..8d8150f 100644
@@ -327,7 +327,7 @@ static int intel_bts_snapshot_start(struct auxtrace_record *itr)
 
 	evlist__for_each(btsr->evlist, evsel) {
 		if (evsel->attr.type == btsr->intel_bts_pmu->type)
-			return perf_evlist__disable_event(btsr->evlist, evsel);
+			return perf_evsel__disable(evsel);
 	}
 	return -EINVAL;
 }
@@ -340,7 +340,7 @@ static int intel_bts_snapshot_finish(struct auxtrace_record *itr)
 
 	evlist__for_each(btsr->evlist, evsel) {
 		if (evsel->attr.type == btsr->intel_bts_pmu->type)
-			return perf_evlist__enable_event(btsr->evlist, evsel);
+			return perf_evsel__enable(evsel);
 	}
 	return -EINVAL;
 }
tools/perf/arch/x86/util/intel-pt.c +2 -2
index b64d462..f05daac 100644
@@ -725,7 +725,7 @@ static int intel_pt_snapshot_start(struct auxtrace_record *itr)
 
 	evlist__for_each(ptr->evlist, evsel) {
 		if (evsel->attr.type == ptr->intel_pt_pmu->type)
-			return perf_evlist__disable_event(ptr->evlist, evsel);
+			return perf_evsel__disable(evsel);
 	}
 	return -EINVAL;
 }
@@ -738,7 +738,7 @@ static int intel_pt_snapshot_finish(struct auxtrace_record *itr)
 
 	evlist__for_each(ptr->evlist, evsel) {
 		if (evsel->attr.type == ptr->intel_pt_pmu->type)
-			return perf_evlist__enable_event(ptr->evlist, evsel);
+			return perf_evsel__enable(evsel);
 	}
 	return -EINVAL;
 }
tools/perf/tests/keep-tracking.c +1 -1
index 6158132..ddb78fa 100644
@@ -123,7 +123,7 @@ int test__keep_tracking(int subtest __maybe_unused)
 
 	evsel = perf_evlist__last(evlist);
 
-	CHECK__(perf_evlist__disable_event(evlist, evsel));
+	CHECK__(perf_evsel__disable(evsel));
 
 	comm = "Test COMM 2";
 	CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));
tools/perf/tests/switch-tracking.c +3 -3
index dfbd8d6..ebd8016 100644
@@ -455,7 +455,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 
 	perf_evlist__enable(evlist);
 
-	err = perf_evlist__disable_event(evlist, cpu_clocks_evsel);
+	err = perf_evsel__disable(cpu_clocks_evsel);
 	if (err) {
 		pr_debug("perf_evlist__disable_event failed!\n");
 		goto out_err;
@@ -474,7 +474,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 		goto out_err;
 	}
 
-	err = perf_evlist__disable_event(evlist, cycles_evsel);
+	err = perf_evsel__disable(cycles_evsel);
 	if (err) {
 		pr_debug("perf_evlist__disable_event failed!\n");
 		goto out_err;
@@ -500,7 +500,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 		goto out_err;
 	}
 
-	err = perf_evlist__enable_event(evlist, cycles_evsel);
+	err = perf_evsel__enable(cycles_evsel);
 	if (err) {
 		pr_debug("perf_evlist__disable_event failed!\n");
 		goto out_err;
tools/perf/util/evlist.c +0 -42

48 lines not on this page · raw message

tools/perf/util/evlist.h +0 -4
index 3b7e1e2..7c4d9a2 100644
@@ -155,10 +155,6 @@ void perf_evlist__disable(struct perf_evlist *evlist);
 void perf_evlist__enable(struct perf_evlist *evlist);
 void perf_evlist__toggle_enable(struct perf_evlist *evlist);
 
-int perf_evlist__disable_event(struct perf_evlist *evlist,
-			       struct perf_evsel *evsel);
-int perf_evlist__enable_event(struct perf_evlist *evlist,
-			      struct perf_evsel *evsel);
 int perf_evlist__enable_event_idx(struct perf_evlist *evlist,
 				  struct perf_evsel *evsel, int idx);
 
author reviewer
#3 lore raw

PATCH v2 2/13 perf tools: Make perf_evlist__open() open evsels with their cpus and threads (like perf record does)

In reply to Jiri Olsa

From: Adrian Hunter <[email protected]>

'perf record' uses perf_evsel__open() to open events and passes the evsel->cpus and evsel->threads. Many tests and some tools instead use perf_evlist__open() which passes instead evlist->cpus and evlist->threads.

Make perf_evlist__open() follow the 'perf record' behaviour so that a consistent approach is taken.

---
 tools/perf/util/evlist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/evlist.c +1 -1
index 05efa910a090..43f4c400a171 100644
@@ -1428,7 +1428,7 @@ int perf_evlist__open(struct perf_evlist *evlist)
 	perf_evlist__update_id_pos(evlist);
 
 	evlist__for_each(evlist, evsel) {
-		err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
+		err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
 		if (err < 0)
 			goto out_err;
 	}
Signature · 1 line
2.4.3
#4 lore raw

[tip:perf/core] perf evlist: Make perf_evlist__open() open evsels with their cpus and threads (like perf record does)

perf evlist: Make perf_evlist__open() open evsels with their cpus and threads (like perf record does)
Commit-ID:  23df7f798435796aff07d641456326b81cb34a77
Gitweb:     http://git.kernel.org/tip/23df7f798435796aff07d641456326b81cb34a77
Author:     Adrian Hunter <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:13:59 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 14:15:11 -0300

perf evlist: Make perf_evlist__open() open evsels with their cpus and threads (like perf record does)

'perf record' uses perf_evsel__open() to open events and passes the evsel->cpus and evsel->threads. Many tests and some tools instead use perf_evlist__open() which passes instead evlist->cpus and evlist->threads.

Make perf_evlist__open() follow the 'perf record' behaviour so that a consistent approach is taken.

---
 tools/perf/util/evlist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/evlist.c +1 -1
index fa6dbf0..29e085b2 100644
@@ -1498,7 +1498,7 @@ int perf_evlist__open(struct perf_evlist *evlist)
 	perf_evlist__update_id_pos(evlist);
 
 	evlist__for_each(evlist, evsel) {
-		err = perf_evsel__open(evsel, evlist->cpus, evlist->threads);
+		err = perf_evsel__open(evsel, evsel->cpus, evsel->threads);
 		if (err < 0)
 			goto out_err;
 	}
author reviewer
#5 lore raw

PATCH v2 3/13 perf tools: Use find_map function in access_dso_mem

In reply to Jiri Olsa

The find_map helper is already there, so let's use it.

Also we're going to introduce wider search in following patch, so it'll be easier to make this change on single place.

---
 tools/perf/util/unwind-libunwind.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
tools/perf/util/unwind-libunwind.c +5 -6
index 3c258a0e4092..f37859c04317 100644
@@ -416,20 +416,19 @@ get_proc_name(unw_addr_space_t __maybe_unused as,
 static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
 			  unw_word_t *data)
 {
-	struct addr_location al;
+	struct map *map;
 	ssize_t size;
 
-	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
-			      MAP__FUNCTION, addr, &al);
-	if (!al.map) {
+	map = find_map(addr, ui);
+	if (!map) {
 		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
 		return -1;
 	}
 
-	if (!al.map->dso)
+	if (!map->dso)
 		return -1;
 
-	size = dso__data_read_addr(al.map->dso, al.map, ui->machine,
+	size = dso__data_read_addr(map->dso, map, ui->machine,
 				   addr, (u8 *) data, sizeof(*data));
 
 	return !(size == sizeof(*data));
Signature · 1 line
2.4.3
#6 lore raw

[tip:perf/core] perf unwind: Use find_map function in access_dso_mem

perf unwind: Use find_map function in access_dso_mem
Commit-ID:  f22ed827a8d5ff5a85e7c8e865baaaaf71a8d0cc
Gitweb:     http://git.kernel.org/tip/f22ed827a8d5ff5a85e7c8e865baaaaf71a8d0cc
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:00 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 14:16:12 -0300

perf unwind: Use find_map function in access_dso_mem

The find_map helper is already there, so let's use it.

Also we're going to introduce wider search in following patch, so it'll be easier to make this change on single place.

---
 tools/perf/util/unwind-libunwind.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
tools/perf/util/unwind-libunwind.c +5 -6
index 3c258a0..f37859c 100644
@@ -416,20 +416,19 @@ get_proc_name(unw_addr_space_t __maybe_unused as,
 static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
 			  unw_word_t *data)
 {
-	struct addr_location al;
+	struct map *map;
 	ssize_t size;
 
-	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
-			      MAP__FUNCTION, addr, &al);
-	if (!al.map) {
+	map = find_map(addr, ui);
+	if (!map) {
 		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
 		return -1;
 	}
 
-	if (!al.map->dso)
+	if (!map->dso)
 		return -1;
 
-	size = dso__data_read_addr(al.map->dso, al.map, ui->machine,
+	size = dso__data_read_addr(map->dso, map, ui->machine,
 				   addr, (u8 *) data, sizeof(*data));
 
 	return !(size == sizeof(*data));
author reviewer
#7 lore raw

PATCH v2 4/13 perf tools libunwind: Check for mmaps also in MAP__VARIABLE tree

In reply to Jiri Olsa

We've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

---
 tools/perf/util/unwind-libunwind.c | 9 +++++++++
 1 file changed, 9 insertions(+)
tools/perf/util/unwind-libunwind.c +9 -0
index f37859c04317..ee7e372297e5 100644
@@ -319,6 +319,15 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
 
 	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
 			      MAP__FUNCTION, ip, &al);
+	if (!al.map) {
+		/*
+		 * We've seen cases (softice) where DWARF unwinder went
+		 * through non executable mmaps, which we need to lookup
+		 * in MAP__VARIABLE tree.
+		 */
+		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
+				      MAP__VARIABLE, ip, &al);
+	}
 	return al.map;
 }
 
Signature · 1 line
2.4.3
#8 lore raw

[tip:perf/core] perf unwind: Check for mmaps also in MAP__VARIABLE tree

perf unwind: Check for mmaps also in MAP__VARIABLE tree
Commit-ID:  0ddf5246f70ecc04e1bb4c4dc2be65977d1c03a7
Gitweb:     http://git.kernel.org/tip/0ddf5246f70ecc04e1bb4c4dc2be65977d1c03a7
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:01 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 14:16:34 -0300

perf unwind: Check for mmaps also in MAP__VARIABLE tree

We've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

---
 tools/perf/util/unwind-libunwind.c | 9 +++++++++
 1 file changed, 9 insertions(+)
tools/perf/util/unwind-libunwind.c +9 -0
index f37859c..ee7e372 100644
@@ -319,6 +319,15 @@ static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
 
 	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
 			      MAP__FUNCTION, ip, &al);
+	if (!al.map) {
+		/*
+		 * We've seen cases (softice) where DWARF unwinder went
+		 * through non executable mmaps, which we need to lookup
+		 * in MAP__VARIABLE tree.
+		 */
+		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
+				      MAP__VARIABLE, ip, &al);
+	}
 	return al.map;
 }
 
author reviewer
#9 lore raw

PATCH v2 5/13 perf tools libdw: Check for mmaps also in MAP__VARIABLE tree

In reply to Jiri Olsa

We've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

---
 tools/perf/util/unwind-libdw.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/unwind-libdw.c +10 -0
index db8142ba7cb9..cf5e250bc78e 100644
@@ -96,6 +96,16 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr,
 	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
 			      MAP__FUNCTION, addr, &al);
 	if (!al.map) {
+		/*
+		 * We've seen cases (softice) where DWARF unwinder went
+		 * through non executable mmaps, which we need to lookup
+		 * in MAP__VARIABLE tree.
+		 */
+		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
+				      MAP__VARIABLE, addr, &al);
+	}
+
+	if (!al.map) {
 		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
 		return -1;
 	}
Signature · 1 line
2.4.3
#10 lore raw

[tip:perf/core] perf libdw: Check for mmaps also in MAP__VARIABLE tree

perf libdw: Check for mmaps also in MAP__VARIABLE tree
Commit-ID:  0ba98149f8c8b6b2ba36be9938afb731fa719004
Gitweb:     http://git.kernel.org/tip/0ba98149f8c8b6b2ba36be9938afb731fa719004
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:02 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 14:16:57 -0300

perf libdw: Check for mmaps also in MAP__VARIABLE tree

We've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

---
 tools/perf/util/unwind-libdw.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
tools/perf/util/unwind-libdw.c +10 -0
index db8142b..cf5e250 100644
@@ -96,6 +96,16 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr,
 	thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
 			      MAP__FUNCTION, addr, &al);
 	if (!al.map) {
+		/*
+		 * We've seen cases (softice) where DWARF unwinder went
+		 * through non executable mmaps, which we need to lookup
+		 * in MAP__VARIABLE tree.
+		 */
+		thread__find_addr_map(ui->thread, PERF_RECORD_MISC_USER,
+				      MAP__VARIABLE, addr, &al);
+	}
+
+	if (!al.map) {
 		pr_debug("unwind: no map for %lx\n", (unsigned long)addr);
 		return -1;
 	}
author reviewer
#11 lore raw

PATCH v2 6/13 perf record: Store data mmaps for dwarf unwind

In reply to Jiri Olsa

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 1 +
 1 file changed, 1 insertion(+)
tools/perf/builtin-record.c +1 -0
index 9c5cdc2c4471..920b93edb497 100644
@@ -804,6 +804,7 @@ int record_parse_callchain_opt(const struct option *opt,
 	int ret;
 	struct record_opts *record = (struct record_opts *)opt->value;
 
+	record->sample_address = true;
 	record->callgraph_set = true;
 	callchain_param.enabled = !unset;
 
Signature · 1 line
2.4.3
maintainer
#12 lore raw

Re: [PATCH 06/13] perf record: Store data mmaps for dwarf unwind

Quoted 20 lines · Jiri Olsa

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 1 +
 1 file changed, 1 insertion(+)
tools/perf/builtin-record.c +0 -0
index 9c5cdc2c4471..920b93edb497 100644

tools/perf/builtin-record.c int record_parse_callchain_opt(const struct option *opt, · line 807

Quoted 4 lines
tools/perf/builtin-record.c +1 -0
@@ -804,6 +804,7 @@ int record_parse_callchain_opt(const struct option *opt,
 	int ret;
 	struct record_opts *record = (struct record_opts *)opt->value;
 
+	record->sample_address = true;

It seems unconditionally set, no?

Thanks,
Namhyung

Quoted 6 lines
tools/perf/builtin-record.c +0 -0
 	record->callgraph_set = true;
 	callchain_param.enabled = !unset;
 
Signature · 1 line
2.4.3
#13 lore raw

PATCH v2 6/13 perf record: Store data mmaps for dwarf unwind

Quoted 24 lines · Namhyung Kim
Quoted 23 lines · Jiri Olsa

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 1 +
 1 file changed, 1 insertion(+)
tools/perf/builtin-record.c +0 -0
index 9c5cdc2c4471..920b93edb497 100644
@@ -804,6 +804,7 @@ int record_parse_callchain_opt(const struct option *opt,
 	int ret;
 	struct record_opts *record = (struct record_opts *)opt->value;
 
Quoted 3 lines

tools/perf/builtin-record.c int record_parse_callchain_opt(const struct option *opt, · line 807

Quoted 1 line
tools/perf/builtin-record.c +1 -0
+	record->sample_address = true;

It seems unconditionally set, no?

ouch, I missed the unset cond down there.. v2 attached

thanks,
jirka

---
Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +4 -1
index 9c5cdc2c4471..465bde77f49b 100644
@@ -815,8 +815,11 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		record->sample_address = true;
 		callchain_debug();
+	}
 
 	return ret;
 }
Signature · 1 line
2.4.3
maintainer
#14 lore raw

Re: [PATCHv2 06/13] perf record: Store data mmaps for dwarf unwind

Quoted 20 lines · Jiri Olsa

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +0 -0
index 9c5cdc2c4471..465bde77f49b 100644

tools/perf/builtin-record.c int record_parse_callchain_opt(const struct option *opt, · line 820

Quoted 7 lines
tools/perf/builtin-record.c +3 -1
@@ -815,8 +815,11 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		record->sample_address = true;

How does it guarantee that it enables data address sampling only for DWARF unwind? Maybe you want this?

		if (callchain_param.record_mode == CALLCHAIN_DWARF)
			record->sample_address = true;

Thanks,
Namhyung

Quoted 8 lines
tools/perf/builtin-record.c +1 -0
 		callchain_debug();
+	}
 
 	return ret;
 }
Signature · 1 line
2.4.3
#15 lore raw

PATCH v3 6/13 perf record: Store data mmaps for dwarf unwind

Quoted 32 lines · Namhyung Kim
Quoted 20 lines · Jiri Olsa

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +0 -0
index 9c5cdc2c4471..465bde77f49b 100644

tools/perf/builtin-record.c int record_parse_callchain_opt(const struct option *opt, · line 820

Quoted 7 lines
tools/perf/builtin-record.c +3 -1
@@ -815,8 +815,11 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		record->sample_address = true;

How does it guarantee that it enables data address sampling only for DWARF unwind? Maybe you want this?

Quoted 2 lines
		if (callchain_param.record_mode == CALLCHAIN_DWARF)
			record->sample_address = true;

ugh.. too much coofee.. :-\ third time's a charm, v3 attached

thanks,
jirka

---
Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +5 -1
index 9c5cdc2c4471..dc4e0adf5c5b 100644
@@ -815,8 +815,12 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		if (callchain_param.record_mode == CALLCHAIN_DWARF)
+			record->sample_address = true;
 		callchain_debug();
+	}
 
 	return ret;
 }
Signature · 1 line
2.4.3
#16 lore raw

Re: [PATCHv3 06/13] perf record: Store data mmaps for dwarf unwind

Em Thu, Jan 07, 2016 at 02:30:22PM +0100, Jiri Olsa escreveu:

Quoted 33 lines · Namhyung Kim
Quoted 32 lines · Jiri Olsa
Quoted 20 lines

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +0 -0
index 9c5cdc2c4471..465bde77f49b 100644

tools/perf/builtin-record.c int record_parse_callchain_opt(const struct option *opt, · line 820

Quoted 7 lines
tools/perf/builtin-record.c +3 -1
@@ -815,8 +815,11 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		record->sample_address = true;

How does it guarantee that it enables data address sampling only for DWARF unwind? Maybe you want this?

Quoted 4 lines
Quoted 2 lines
		if (callchain_param.record_mode == CALLCHAIN_DWARF)
			record->sample_address = true;

ugh.. too much coofee.. :-\ third time's a charm, v3 attached

Noel, have you tested this latest patch? Does it fix things for you in this latest iteration?

If so, can I stick a "Reported-and-Tested-by: Noel Grandin <>" to this?

Quoted 40 lines

thanks,
jirka

---
Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +5 -1
index 9c5cdc2c4471..dc4e0adf5c5b 100644
@@ -815,8 +815,12 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		if (callchain_param.record_mode == CALLCHAIN_DWARF)
+			record->sample_address = true;
 		callchain_debug();
+	}
 
 	return ret;
 }
Signature · 1 line
2.4.3
#17 lore raw

[tip:perf/core] perf record: Store data mmaps for dwarf unwind

In reply to Jiri Olsa
perf record: Store data mmaps for dwarf unwind
Commit-ID:  5c0cf22477eaa890beeb4bc3554e5bebbea4b007
Gitweb:     http://git.kernel.org/tip/5c0cf22477eaa890beeb4bc3554e5bebbea4b007
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 14:30:22 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 14:17:45 -0300

perf record: Store data mmaps for dwarf unwind

Currently we don't synthesize data mmap by default. It depends on -d option, that enables data address sampling.

But we've seen cases (softice) where DWARF unwinder went through non executable mmaps, which we need to lookup in MAP__VARIABLE tree.

Making data mmaps to be synthesized for dwarf unwind as well.

---
 tools/perf/builtin-record.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
tools/perf/builtin-record.c +5 -1
index 9c5cdc2c4..dc4e0ad 100644
@@ -815,8 +815,12 @@ int record_parse_callchain_opt(const struct option *opt,
 	}
 
 	ret = parse_callchain_record_opt(arg, &callchain_param);
-	if (!ret)
+	if (!ret) {
+		/* Enable data address sampling for DWARF unwind. */
+		if (callchain_param.record_mode == CALLCHAIN_DWARF)
+			record->sample_address = true;
 		callchain_debug();
+	}
 
 	return ret;
 }
author reviewer
#18 lore raw

PATCH v2 7/13 perf tools: Do not show trace command if it's not compiled in

In reply to Jiri Olsa

The trace command still appears in help message when you run simple 'perf' command.

It's because the generate-cmdlist.sh does not care about the HAVE_LIBAUDIT_SUPPORT dependency of trace command and puts it into generated common_cmds array.

Wrapping trace command under HAVE_LIBAUDIT_SUPPORT dependency, which will exclude it from common_cmds array if HAVE_LIBAUDIT_SUPPORT is not set.

---
 tools/perf/command-list.txt         |  2 +-
 tools/perf/util/generate-cmdlist.sh | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
tools/perf/command-list.txt +1 -1
index acc3ea7d90b7..ab5cbaa170d0 100644
@@ -26,4 +26,4 @@ perf-stat			mainporcelain common
 perf-test			mainporcelain common
 perf-timechart			mainporcelain common
 perf-top			mainporcelain common
-perf-trace			mainporcelain common
+perf-trace			mainporcelain audit
tools/perf/util/generate-cmdlist.sh +15 -0
index 36a885d2cd22..0ac2037c970c 100755
@@ -36,4 +36,19 @@ do
      }' "Documentation/perf-$cmd.txt"
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
+
+echo "#ifdef HAVE_LIBAUDIT_SUPPORT"
+sed -n -e 's/^perf-\([^ 	]*\)[ 	].* audit*/\1/p' command-list.txt |
+sort |
+while read cmd
+do
+     sed -n '
+     /^NAME/,/perf-'"$cmd"'/H
+     ${
+            x
+            s/.*perf-'"$cmd"' - \(.*\)/  {"'"$cmd"'", "\1"},/
+	    p
+     }' "Documentation/perf-$cmd.txt"
+done
+echo "#endif /* HAVE_LIBELF_SUPPORT */"
 echo "};"
Signature · 1 line
2.4.3
#19 lore raw

[tip:perf/core] perf tools: Do not show trace command if it' s not compiled in

perf tools: Do not show trace command if it's not compiled in
Commit-ID:  cbd08b7335c9d559f424dcef7bea333605597490
Gitweb:     http://git.kernel.org/tip/cbd08b7335c9d559f424dcef7bea333605597490
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:04 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:46:17 -0300

perf tools: Do not show trace command if it's not compiled in

The trace command still appears in help message when you run simple 'perf' command.

It's because the generate-cmdlist.sh does not care about the HAVE_LIBAUDIT_SUPPORT dependency of trace command and puts it into generated common_cmds array.

Wrapping trace command under HAVE_LIBAUDIT_SUPPORT dependency, which will exclude it from common_cmds array if HAVE_LIBAUDIT_SUPPORT is not set.

---
 tools/perf/command-list.txt         |  2 +-
 tools/perf/util/generate-cmdlist.sh | 15 +++++++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
tools/perf/command-list.txt +1 -1
index acc3ea7..ab5cbaa 100644
@@ -26,4 +26,4 @@ perf-stat			mainporcelain common
 perf-test			mainporcelain common
 perf-timechart			mainporcelain common
 perf-top			mainporcelain common
-perf-trace			mainporcelain common
+perf-trace			mainporcelain audit
tools/perf/util/generate-cmdlist.sh +15 -0
index 36a885d..0ac2037 100755
@@ -36,4 +36,19 @@ do
      }' "Documentation/perf-$cmd.txt"
 done
 echo "#endif /* HAVE_LIBELF_SUPPORT */"
+
+echo "#ifdef HAVE_LIBAUDIT_SUPPORT"
+sed -n -e 's/^perf-\([^ 	]*\)[ 	].* audit*/\1/p' command-list.txt |
+sort |
+while read cmd
+do
+     sed -n '
+     /^NAME/,/perf-'"$cmd"'/H
+     ${
+            x
+            s/.*perf-'"$cmd"' - \(.*\)/  {"'"$cmd"'", "\1"},/
+	    p
+     }' "Documentation/perf-$cmd.txt"
+done
+echo "#endif /* HAVE_LIBELF_SUPPORT */"
 echo "};"
author reviewer
#20 lore raw

PATCH v2 8/13 perf script: Align event name properly

In reply to Jiri Olsa

Adding code to align event names, so we get aligned output in case of multiple events with different names.

Before:

  $ perf script
  :13757 13757 163918.230829: cpu/mem-snp-none/P: ffff88085f20d010
  :13757 13757 163918.230832: cpu/mem-loads,ldlat=30/P:     7f5a5f719f00
  :13757 13757 163918.230835: cpu/mem-loads,ldlat=30/P:     7f5a5f719f00
  :13758 13758 163918.230838: cpu/mem-snp-none/P: ffff88085f4ad810
  :13758 13758 163918.154093: cpu/mem-stores/P: ffff88085bb53f28
  :13757 13757 163918.155264: cpu/mem-snp-hitm/P:           601080
  ...

After:

  $ perf script
  :13757 13757 163918.228831:       cpu/mem-snp-none/P: ffffffff81a841c0
  :13757 13757 163918.228834: cpu/mem-loads,ldlat=30/P:     7f5a5f719f08
  :13757 13757 163918.228837: cpu/mem-loads,ldlat=30/P:     7f5a5f719f08
  :13758 13758 163918.228837:       cpu/mem-snp-none/P: ffff88085f4ad800
  :13758 13758 163918.154093:         cpu/mem-stores/P: ffff88085bb53f28
  :13757 13757 163918.155264:       cpu/mem-snp-hitm/P:           601080
  ...
---
 tools/perf/builtin-script.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
tools/perf/builtin-script.c +22 -2
index 5e2f9d20a296..c691214d820f 100644
@@ -617,9 +617,24 @@ struct perf_script {
 	bool			allocated;
 	struct cpu_map		*cpus;
 	struct thread_map	*threads;
+	int			name_width;
 };
 
-static void process_event(struct perf_script *script __maybe_unused, union perf_event *event,
+static int perf_evlist__max_name_len(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+	int max = 0;
+
+	evlist__for_each(evlist, evsel) {
+		int len = strlen(perf_evsel__name(evsel));
+
+		max = MAX(len, max);
+	}
+
+	return max;
+}
+
+static void process_event(struct perf_script *script, union perf_event *event,
 			  struct perf_sample *sample, struct perf_evsel *evsel,
 			  struct addr_location *al)
 {
@@ -636,7 +651,12 @@ static void process_event(struct perf_script *script __maybe_unused, union perf_
 
 	if (PRINT_FIELD(EVNAME)) {
 		const char *evname = perf_evsel__name(evsel);
-		printf("%s: ", evname ? evname : "[unknown]");
+
+		if (!script->name_width)
+			script->name_width = perf_evlist__max_name_len(script->session->evlist);
+
+		printf("%*s: ", script->name_width,
+		       evname ? evname : "[unknown]");
 	}
 
 	if (print_flags)
Signature · 1 line
2.4.3
#21 lore raw

[tip:perf/core] perf script: Align event name properly

perf script: Align event name properly
Commit-ID:  9cdbc409626b29ab30f06a6393db6763f040f753
Gitweb:     http://git.kernel.org/tip/9cdbc409626b29ab30f06a6393db6763f040f753
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:05 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:57:26 -0300

perf script: Align event name properly

Adding code to align event names, so we get aligned output in case of multiple events with different names.

Before:

  $ perf script
  :13757 13757 163918.230829: cpu/mem-snp-none/P: ffff88085f20d010
  :13757 13757 163918.230832: cpu/mem-loads,ldlat=30/P:     7f5a5f719f00
  :13757 13757 163918.230835: cpu/mem-loads,ldlat=30/P:     7f5a5f719f00
  :13758 13758 163918.230838: cpu/mem-snp-none/P: ffff88085f4ad810
  :13758 13758 163918.154093: cpu/mem-stores/P: ffff88085bb53f28
  :13757 13757 163918.155264: cpu/mem-snp-hitm/P:           601080
  ...

After:

  $ perf script
  :13757 13757 163918.228831:       cpu/mem-snp-none/P: ffffffff81a841c0
  :13757 13757 163918.228834: cpu/mem-loads,ldlat=30/P:     7f5a5f719f08
  :13757 13757 163918.228837: cpu/mem-loads,ldlat=30/P:     7f5a5f719f08
  :13758 13758 163918.228837:       cpu/mem-snp-none/P: ffff88085f4ad800
  :13758 13758 163918.154093:         cpu/mem-stores/P: ffff88085bb53f28
  :13757 13757 163918.155264:       cpu/mem-snp-hitm/P:           601080
  ...
---
 tools/perf/builtin-script.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
tools/perf/builtin-script.c +22 -2
index 5e2f9d2..c691214 100644
@@ -617,9 +617,24 @@ struct perf_script {
 	bool			allocated;
 	struct cpu_map		*cpus;
 	struct thread_map	*threads;
+	int			name_width;
 };
 
-static void process_event(struct perf_script *script __maybe_unused, union perf_event *event,
+static int perf_evlist__max_name_len(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel;
+	int max = 0;
+
+	evlist__for_each(evlist, evsel) {
+		int len = strlen(perf_evsel__name(evsel));
+
+		max = MAX(len, max);
+	}
+
+	return max;
+}
+
+static void process_event(struct perf_script *script, union perf_event *event,
 			  struct perf_sample *sample, struct perf_evsel *evsel,
 			  struct addr_location *al)
 {
@@ -636,7 +651,12 @@ static void process_event(struct perf_script *script __maybe_unused, union perf_
 
 	if (PRINT_FIELD(EVNAME)) {
 		const char *evname = perf_evsel__name(evsel);
-		printf("%s: ", evname ? evname : "[unknown]");
+
+		if (!script->name_width)
+			script->name_width = perf_evlist__max_name_len(script->session->evlist);
+
+		printf("%*s: ", script->name_width,
+		       evname ? evname : "[unknown]");
 	}
 
 	if (print_flags)
author reviewer
#22 lore raw

PATCH v2 9/13 perf tools: Include all tools/lib directory for tags/cscope/TAGS targets

In reply to Jiri Olsa

Besides lockdep we use all the 'tools/lib' code in perf, so include it completely in tags.

---
 tools/perf/Makefile.perf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/Makefile.perf +1 -1
index 404e3b1c4e31..1025ea79b90b 100644
@@ -488,7 +488,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
 $(DOC_TARGETS):
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
 
-TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol ../include ../lib/bpf
+TAG_FOLDERS= . ../lib ../include
 TAG_FILES= ../../include/uapi/linux/perf_event.h
 
 TAGS:
Signature · 1 line
2.4.3
#23 lore raw

[tip:perf/core] perf tools: Include all tools/ lib directory for tags/cscope/TAGS targets

perf tools: Include all tools/lib directory for tags/cscope/TAGS targets
Commit-ID:  685c84154cef61dd7d961f36ab92f13c3ef5d354
Gitweb:     http://git.kernel.org/tip/685c84154cef61dd7d961f36ab92f13c3ef5d354
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:06 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:57:46 -0300

perf tools: Include all tools/lib directory for tags/cscope/TAGS targets

Besides lockdep we use all the 'tools/lib' code in perf, so include it completely in tags.

---
 tools/perf/Makefile.perf | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/Makefile.perf +1 -1
index 404e3b1..1025ea7 100644
@@ -488,7 +488,7 @@ INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
 $(DOC_TARGETS):
 	$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
 
-TAG_FOLDERS= . ../lib/traceevent ../lib/api ../lib/symbol ../include ../lib/bpf
+TAG_FOLDERS= . ../lib ../include
 TAG_FILES= ../../include/uapi/linux/perf_event.h
 
 TAGS:
author reviewer
#24 lore raw

PATCH v2 10/13 perf tools: Remove list entry from struct sort_entry

In reply to Jiri Olsa

It's no longer needed.

---
 tools/perf/util/sort.h | 2 --
 1 file changed, 2 deletions(-)
tools/perf/util/sort.h +0 -2
index dec536b6ab3d..687bbb124428 100644
@@ -214,8 +214,6 @@ enum sort_type {
  */
 
 struct sort_entry {
-	struct list_head list;
-
 	const char *se_header;
 
 	int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
Signature · 1 line
2.4.3
maintainer Acked-by on v2 10/13
#25 lore raw

Re: [PATCH 10/13] perf tools: Remove list entry from struct sort_entry

Quoted 4 lines · Jiri Olsa

It's no longer needed.

Thanks,
Namhyung

Quoted 20 lines
---
 tools/perf/util/sort.h | 2 --
 1 file changed, 2 deletions(-)
tools/perf/util/sort.h +0 -2
index dec536b6ab3d..687bbb124428 100644
@@ -214,8 +214,6 @@ enum sort_type {
  */
 
 struct sort_entry {
-	struct list_head list;
-
 	const char *se_header;
 
 	int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
Signature · 1 line
2.4.3
#26 lore raw

[tip:perf/core] perf tools: Remove list entry from struct sort_entry

In reply to Jiri Olsa
perf tools: Remove list entry from struct sort_entry
Commit-ID:  bb4ced29f5d5ff1d4d51b602dad34a0d15495a67
Gitweb:     http://git.kernel.org/tip/bb4ced29f5d5ff1d4d51b602dad34a0d15495a67
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:07 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:58:04 -0300

perf tools: Remove list entry from struct sort_entry

It's no longer needed.

---
 tools/perf/util/sort.h | 2 --
 1 file changed, 2 deletions(-)
tools/perf/util/sort.h +0 -2
index dec536b..687bbb12 100644
@@ -214,8 +214,6 @@ enum sort_type {
  */
 
 struct sort_entry {
-	struct list_head list;
-
 	const char *se_header;
 
 	int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
author reviewer
#27 lore raw

PATCH v2 11/13 perf tools: Add overhead/overhead_children keys defaults via string

In reply to Jiri Olsa

We currently set 'overhead' and 'overhead_children' as default sort keys within perf_hpp__init function by directly adding into the sort list.

This patch adds 'overhead' and 'overhead_children' in text form into sort_keys and let them be added by standard sort dimension interface.

We need to eliminate dirrect sort_list additions to b able to add support for hists specific sort keys.

---
 tools/perf/ui/hist.c   | 12 ------------
 tools/perf/util/sort.c | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 12 deletions(-)
tools/perf/ui/hist.c +0 -12
index 8263c0eb9fb5..bf2a66e254ea 100644
@@ -443,7 +443,6 @@ LIST_HEAD(perf_hpp__sort_list);
 
 void perf_hpp__init(void)
 {
-	struct list_head *list;
 	int i;
 
 	for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
@@ -484,17 +483,6 @@ void perf_hpp__init(void)
 
 	if (symbol_conf.show_total_period)
 		hpp_dimension__add_output(PERF_HPP__PERIOD);
-
-	/* prepend overhead field for backward compatiblity.  */
-	list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
-	if (list_empty(list))
-		list_add(list, &perf_hpp__sort_list);
-
-	if (symbol_conf.cumulate_callchain) {
-		list = &perf_hpp__format[PERF_HPP__OVERHEAD_ACC].sort_list;
-		if (list_empty(list))
-			list_add(list, &perf_hpp__sort_list);
-	}
 }
 
 void perf_hpp__column_register(struct perf_hpp_fmt *format)
tools/perf/util/sort.c +39 -0
index 04e2a5cb19e3..ec722346e6ff 100644
@@ -2252,6 +2252,34 @@ static int setup_sort_order(struct perf_evlist *evlist)
 	return 0;
 }
 
+/*
+ * Adds 'pre,' prefix into 'str' is 'pre' is
+ * not already part of 'str'.
+ */
+static char *prefix_if_not_in(const char *pre, char *str)
+{
+	char *n;
+
+	if (!str || strstr(str, pre))
+		return str;
+
+	if (asprintf(&n, "%s,%s", pre, str) < 0)
+		return NULL;
+
+	free(str);
+	return n;
+}
+
+static char *setup_overhead(char *keys)
+{
+	keys = prefix_if_not_in("overhead", keys);
+
+	if (symbol_conf.cumulate_callchain)
+		keys = prefix_if_not_in("overhead_children", keys);
+
+	return keys;
+}
+
 static int __setup_sorting(struct perf_evlist *evlist)
 {
 	char *tmp, *tok, *str;
@@ -2281,6 +2309,17 @@ static int __setup_sorting(struct perf_evlist *evlist)
 		return -ENOMEM;
 	}
 
+	/*
+	 * Prepend overhead fields for backward compatibility.
+	 */
+	if (!is_strict_order(field_order)) {
+		str = setup_overhead(str);
+		if (str == NULL) {
+			error("Not enough memory to setup overhead keys");
+			return -ENOMEM;
+		}
+	}
+
 	for (tok = strtok_r(str, ", ", &tmp);
 			tok; tok = strtok_r(NULL, ", ", &tmp)) {
 		ret = sort_dimension__add(tok, evlist);
Signature · 1 line
2.4.3
maintainer Acked-by on v2 11/13
#28 lore raw

Re: [PATCH 11/13] perf tools: Add overhead/overhead_children keys defaults via string

Quoted 8 lines · Jiri Olsa

We currently set 'overhead' and 'overhead_children' as default sort keys within perf_hpp__init function by directly adding into the sort list.

This patch adds 'overhead' and 'overhead_children' in text form into sort_keys and let them be added by standard sort dimension interface.

Quoted 5 lines

We need to eliminate dirrect sort_list additions to b able to add support for hists specific sort keys.

Thanks,
Namhyung

Quoted 95 lines
---
 tools/perf/ui/hist.c   | 12 ------------
 tools/perf/util/sort.c | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 12 deletions(-)
tools/perf/ui/hist.c +0 -12
index 8263c0eb9fb5..bf2a66e254ea 100644
@@ -443,7 +443,6 @@ LIST_HEAD(perf_hpp__sort_list);
 
 void perf_hpp__init(void)
 {
-	struct list_head *list;
 	int i;
 
 	for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
@@ -484,17 +483,6 @@ void perf_hpp__init(void)
 
 	if (symbol_conf.show_total_period)
 		hpp_dimension__add_output(PERF_HPP__PERIOD);
-
-	/* prepend overhead field for backward compatiblity.  */
-	list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
-	if (list_empty(list))
-		list_add(list, &perf_hpp__sort_list);
-
-	if (symbol_conf.cumulate_callchain) {
-		list = &perf_hpp__format[PERF_HPP__OVERHEAD_ACC].sort_list;
-		if (list_empty(list))
-			list_add(list, &perf_hpp__sort_list);
-	}
 }
 
 void perf_hpp__column_register(struct perf_hpp_fmt *format)
tools/perf/util/sort.c +39 -0
index 04e2a5cb19e3..ec722346e6ff 100644
@@ -2252,6 +2252,34 @@ static int setup_sort_order(struct perf_evlist *evlist)
 	return 0;
 }
 
+/*
+ * Adds 'pre,' prefix into 'str' is 'pre' is
+ * not already part of 'str'.
+ */
+static char *prefix_if_not_in(const char *pre, char *str)
+{
+	char *n;
+
+	if (!str || strstr(str, pre))
+		return str;
+
+	if (asprintf(&n, "%s,%s", pre, str) < 0)
+		return NULL;
+
+	free(str);
+	return n;
+}
+
+static char *setup_overhead(char *keys)
+{
+	keys = prefix_if_not_in("overhead", keys);
+
+	if (symbol_conf.cumulate_callchain)
+		keys = prefix_if_not_in("overhead_children", keys);
+
+	return keys;
+}
+
 static int __setup_sorting(struct perf_evlist *evlist)
 {
 	char *tmp, *tok, *str;
@@ -2281,6 +2309,17 @@ static int __setup_sorting(struct perf_evlist *evlist)
 		return -ENOMEM;
 	}
 
+	/*
+	 * Prepend overhead fields for backward compatibility.
+	 */
+	if (!is_strict_order(field_order)) {
+		str = setup_overhead(str);
+		if (str == NULL) {
+			error("Not enough memory to setup overhead keys");
+			return -ENOMEM;
+		}
+	}
+
 	for (tok = strtok_r(str, ", ", &tmp);
 			tok; tok = strtok_r(NULL, ", ", &tmp)) {
 		ret = sort_dimension__add(tok, evlist);
Signature · 1 line
2.4.3
#29 lore raw

[tip:perf/core] perf tools: Add overhead/ overhead_children keys defaults via string

In reply to Jiri Olsa
perf tools: Add overhead/overhead_children keys defaults via string
Commit-ID:  b97511c5bc94ef12613f485ab82f989df04088da
Gitweb:     http://git.kernel.org/tip/b97511c5bc94ef12613f485ab82f989df04088da
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:08 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:58:58 -0300

perf tools: Add overhead/overhead_children keys defaults via string

We currently set 'overhead' and 'overhead_children' as default sort keys within perf_hpp__init function by directly adding into the sort list.

This patch adds 'overhead' and 'overhead_children' in text form into sort_keys and let them be added by standard sort dimension interface.

We need to eliminate dirrect sort_list additions to be able to add support for hists specific sort keys.

---
 tools/perf/ui/hist.c   | 12 ------------
 tools/perf/util/sort.c | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 12 deletions(-)
tools/perf/ui/hist.c +0 -12
index 8263c0e..bf2a66e 100644
@@ -443,7 +443,6 @@ LIST_HEAD(perf_hpp__sort_list);
 
 void perf_hpp__init(void)
 {
-	struct list_head *list;
 	int i;
 
 	for (i = 0; i < PERF_HPP__MAX_INDEX; i++) {
@@ -484,17 +483,6 @@ void perf_hpp__init(void)
 
 	if (symbol_conf.show_total_period)
 		hpp_dimension__add_output(PERF_HPP__PERIOD);
-
-	/* prepend overhead field for backward compatiblity.  */
-	list = &perf_hpp__format[PERF_HPP__OVERHEAD].sort_list;
-	if (list_empty(list))
-		list_add(list, &perf_hpp__sort_list);
-
-	if (symbol_conf.cumulate_callchain) {
-		list = &perf_hpp__format[PERF_HPP__OVERHEAD_ACC].sort_list;
-		if (list_empty(list))
-			list_add(list, &perf_hpp__sort_list);
-	}
 }
 
 void perf_hpp__column_register(struct perf_hpp_fmt *format)
tools/perf/util/sort.c +39 -0
index 04e2a5c..ec72234 100644
@@ -2252,6 +2252,34 @@ static int setup_sort_order(struct perf_evlist *evlist)
 	return 0;
 }
 
+/*
+ * Adds 'pre,' prefix into 'str' is 'pre' is
+ * not already part of 'str'.
+ */
+static char *prefix_if_not_in(const char *pre, char *str)
+{
+	char *n;
+
+	if (!str || strstr(str, pre))
+		return str;
+
+	if (asprintf(&n, "%s,%s", pre, str) < 0)
+		return NULL;
+
+	free(str);
+	return n;
+}
+
+static char *setup_overhead(char *keys)
+{
+	keys = prefix_if_not_in("overhead", keys);
+
+	if (symbol_conf.cumulate_callchain)
+		keys = prefix_if_not_in("overhead_children", keys);
+
+	return keys;
+}
+
 static int __setup_sorting(struct perf_evlist *evlist)
 {
 	char *tmp, *tok, *str;
@@ -2281,6 +2309,17 @@ static int __setup_sorting(struct perf_evlist *evlist)
 		return -ENOMEM;
 	}
 
+	/*
+	 * Prepend overhead fields for backward compatibility.
+	 */
+	if (!is_strict_order(field_order)) {
+		str = setup_overhead(str);
+		if (str == NULL) {
+			error("Not enough memory to setup overhead keys");
+			return -ENOMEM;
+		}
+	}
+
 	for (tok = strtok_r(str, ", ", &tmp);
 			tok; tok = strtok_r(NULL, ", ", &tmp)) {
 		ret = sort_dimension__add(tok, evlist);
author reviewer
#30 lore raw

PATCH v2 12/13 perf diff: Use perf_hpp__register_sort_field interface

In reply to Jiri Olsa

Using perf_hpp__register_sort_field interface
instead of directly adding the entry.

---
 tools/perf/builtin-diff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-diff.c +1 -1
index 87063835d741..36ccc2b8827f 100644
@@ -1207,7 +1207,7 @@ static int ui_init(void)
 		BUG_ON(1);
 	}
 
-	list_add(&fmt->sort_list, &perf_hpp__sort_list);
+	perf_hpp__register_sort_field(fmt);
 	return 0;
 }
 
Signature · 1 line
2.4.3
maintainer Acked-by on v2 12/13
#31 lore raw

Re: [PATCH 12/13] perf diff: Use perf_hpp__register_sort_field interface

Quoted 5 lines · Jiri Olsa

Using perf_hpp__register_sort_field interface
instead of directly adding the entry.

Thanks,
Namhyung

Quoted 20 lines
---
 tools/perf/builtin-diff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-diff.c +1 -1
index 87063835d741..36ccc2b8827f 100644
@@ -1207,7 +1207,7 @@ static int ui_init(void)
 		BUG_ON(1);
 	}
 
-	list_add(&fmt->sort_list, &perf_hpp__sort_list);
+	perf_hpp__register_sort_field(fmt);
 	return 0;
 }
 
Signature · 1 line
2.4.3
#32 lore raw

[tip:perf/core] perf diff: Use perf_hpp__register_sort_field interface

In reply to Jiri Olsa
perf diff: Use perf_hpp__register_sort_field interface
Commit-ID:  21e6d8428664293f203be3004dcd8d70f68ebdb9
Gitweb:     http://git.kernel.org/tip/21e6d8428664293f203be3004dcd8d70f68ebdb9
Author:     Jiri Olsa <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:09 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:59:30 -0300

perf diff: Use perf_hpp__register_sort_field interface

Using perf_hpp__register_sort_field interface instead of directly adding the entry.

---
 tools/perf/builtin-diff.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-diff.c +1 -1
index 8706383..36ccc2b 100644
@@ -1207,7 +1207,7 @@ static int ui_init(void)
 		BUG_ON(1);
 	}
 
-	list_add(&fmt->sort_list, &perf_hpp__sort_list);
+	perf_hpp__register_sort_field(fmt);
 	return 0;
 }
 
author reviewer
#33 lore raw

PATCH v2 13/13 perf tools: Export a couple of hist functions

In reply to Jiri Olsa

From: Namhyung Kim <[email protected]>

These are necessary for multi threaded sample processing:

- hists__get__get_rotate_entries_in()
- hists__collapse_insert_entry()
- __hists__init()

---
 tools/perf/util/hist.c | 19 ++++++++++++-------
 tools/perf/util/hist.h |  5 +++++
 2 files changed, 17 insertions(+), 7 deletions(-)
tools/perf/util/hist.c +12 -7
index afc9b8f1b36c..f2d5c5c287c4 100644
@@ -1006,9 +1006,8 @@ void hist_entry__delete(struct hist_entry *he)
  * collapse the histogram
  */
 
-static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
-					 struct rb_root *root,
-					 struct hist_entry *he)
+bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+				  struct rb_root *root, struct hist_entry *he)
 {
 	struct rb_node **p = &root->rb_node;
 	struct rb_node *parent = NULL;
@@ -1048,7 +1047,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
 	return true;
 }
 
-static struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
+struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
 {
 	struct rb_root *root;
 
@@ -1583,10 +1582,8 @@ int perf_hist_config(const char *var, const char *value)
 	return 0;
 }
 
-static int hists_evsel__init(struct perf_evsel *evsel)
+int __hists__init(struct hists *hists)
 {
-	struct hists *hists = evsel__hists(evsel);
-
 	memset(hists, 0, sizeof(*hists));
 	hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
 	hists->entries_in = &hists->entries_in_array[0];
@@ -1626,6 +1623,14 @@ static void hists_evsel__exit(struct perf_evsel *evsel)
 	hists__delete_all_entries(hists);
 }
 
+static int hists_evsel__init(struct perf_evsel *evsel)
+{
+	struct hists *hists = evsel__hists(evsel);
+
+	__hists__init(hists);
+	return 0;
+}
+
 /*
  * XXX We probably need a hists_evsel__exit() to free the hist_entries
  * stored in the rbtree...
tools/perf/util/hist.h +5 -0
index cb8f37349972..d4ec4822a103 100644
@@ -185,6 +185,11 @@ static inline struct hists *evsel__hists(struct perf_evsel *evsel)
 }
 
 int hists__init(void);
+int __hists__init(struct hists *hists);
+
+struct rb_root *hists__get_rotate_entries_in(struct hists *hists);
+bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+				  struct rb_root *root, struct hist_entry *he);
 
 struct perf_hpp {
 	char *buf;
Signature · 1 line
2.4.3
#34 lore raw

[tip:perf/core] perf hists: Export a couple of hist functions

perf hists: Export a couple of hist functions
Commit-ID:  fc284be9d88528dd2a28d5471e40a6acde6c3036
Gitweb:     http://git.kernel.org/tip/fc284be9d88528dd2a28d5471e40a6acde6c3036
Author:     Namhyung Kim <[email protected]>
AuthorDate: Thu, 7 Jan 2016 10:14:10 +0100
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 8 Jan 2016 12:59:48 -0300

perf hists: Export a couple of hist functions

These are necessary for multi threaded sample processing:

- hists__get__get_rotate_entries_in()
- hists__collapse_insert_entry()
- __hists__init()

---
 tools/perf/util/hist.c | 19 ++++++++++++-------
 tools/perf/util/hist.h |  5 +++++
 2 files changed, 17 insertions(+), 7 deletions(-)
tools/perf/util/hist.c +12 -7
index 888776b..c226303 100644
@@ -1007,9 +1007,8 @@ void hist_entry__delete(struct hist_entry *he)
  * collapse the histogram
  */
 
-static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
-					 struct rb_root *root,
-					 struct hist_entry *he)
+bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+				  struct rb_root *root, struct hist_entry *he)
 {
 	struct rb_node **p = &root->rb_node;
 	struct rb_node *parent = NULL;
@@ -1049,7 +1048,7 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
 	return true;
 }
 
-static struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
+struct rb_root *hists__get_rotate_entries_in(struct hists *hists)
 {
 	struct rb_root *root;
 
@@ -1584,10 +1583,8 @@ int perf_hist_config(const char *var, const char *value)
 	return 0;
 }
 
-static int hists_evsel__init(struct perf_evsel *evsel)
+int __hists__init(struct hists *hists)
 {
-	struct hists *hists = evsel__hists(evsel);
-
 	memset(hists, 0, sizeof(*hists));
 	hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
 	hists->entries_in = &hists->entries_in_array[0];
@@ -1627,6 +1624,14 @@ static void hists_evsel__exit(struct perf_evsel *evsel)
 	hists__delete_all_entries(hists);
 }
 
+static int hists_evsel__init(struct perf_evsel *evsel)
+{
+	struct hists *hists = evsel__hists(evsel);
+
+	__hists__init(hists);
+	return 0;
+}
+
 /*
  * XXX We probably need a hists_evsel__exit() to free the hist_entries
  * stored in the rbtree...
tools/perf/util/hist.h +5 -0
index cb8f373..d4ec482 100644
@@ -185,6 +185,11 @@ static inline struct hists *evsel__hists(struct perf_evsel *evsel)
 }
 
 int hists__init(void);
+int __hists__init(struct hists *hists);
+
+struct rb_root *hists__get_rotate_entries_in(struct hists *hists);
+bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+				  struct rb_root *root, struct hist_entry *he);
 
 struct perf_hpp {
 	char *buf;