linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL 00/15] perf/core improvements
@ 2016-04-15 21:50 Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 01/15] perf trace: Move socket_type beautifier to tools/perf/trace/beauty/ Arnaldo Carvalho de Melo
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Frederic Weisbecker, Jiri Olsa, Milian Wolff,
	Namhyung Kim, Wang Nan, Arnaldo Carvalho de Melo

Hi Ingo,

	Please consider pulling,

- Arnaldo

The following changes since commit 0b22cd276cec21107d9d69453fa58abba73e71df:

  Merge tag 'perf-core-for-mingo-20160414' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2016-04-14 15:30:59 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160415

for you to fetch changes up to f3e459d16a8493b617ccf2a940330279679e0291:

  perf trace: Bump --mmap-pages when --call-graph is used by the root user (2016-04-15 17:52:34 -0300)

----------------------------------------------------------------
perf/core improvements:

User visible:

- Wire the callchain unwinding "max-stack" know to 'perf script --max-stack',
  allowing to limit the depth of callchains, possibly reducing processing
  time (Arnaldo Carvalho de Melo)

- Ditto for 'perf trace --max-stack' (Arnaldo Carvalho de Melo)

- Introduce a --min-stack filter for 'perf trace', to show syscalls that
  had a userspace callchain leading to it at least min-stack deep (Arnaldo Carvalho de Melo)

- Make 'perf trace' work with multiple threads and the --duration filter,
  i.e. do not print the start of an interrupted syscall followed by ...
  to print interrupts from other threads, as we need to wait the sys_exit
  syscall tracepoint to calculate the duration, duh. (Arnaldo Carvalho de Melo)

  System wide --duration now works as expected:

   [root@jouet ~]# trace --duration 100
     152.393 (145.147 ms): Timer/24358 futex(uaddr: 0x7f5ed98e56cc, op: WAIT_BITSET|PRIV|CLKRT, val: 7055125, utime: 0x7f5ecdbfec30, val3: 4294967295) = -1 ETIMEDOUT Connection timed out
     152.438 (145.040 ms): firefox/24321 poll(ufds: 0x7f5ec388b460, nfds: 6, timeout_msecs: 4294967295) = 1
     358.580 (158.279 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x7ffdcbb63610) = 0 Timeout
     358.687 (148.285 ms): gnome-terminal/2711 poll(ufds: 0x55b7e6811ad0, nfds: 15, timeout_msecs: 249) = 1
     370.150 (169.569 ms): gnome-shell/2287 poll(ufds: 0x55e623d65490, nfds: 86, timeout_msecs: 4294967295) = 1

- Now 'perf trace's --max-stack and --min-stack will automatically set
  "--call-graph dwarf", if --call-graph is not present on the command line:

   [root@jouet ~]# perf trace -e nanosleep --max-stack 3 usleep 1
     0.299 ( 0.057 ms): usleep/29658 nanosleep(rqtp: 0x7fff80f3b230) = 0
                                       __nanosleep+0x10 (/usr/lib64/libc-2.22.so)
                                       usleep+0x34 (/usr/lib64/libc-2.22.so)
                                       main+0x1eb (/usr/bin/usleep)
   [root@jouet ~]#

- Bump 'perf trace --mmap-pages' for root when using callchains and not
  specifying --mmap-pages explicitely (Arnaldo Carvalho de Melo)

Build fixes:

- The python binding object had missing symbols, to some refactoring
  to fix that (Arnaldo Carvalho de Melo)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

----------------------------------------------------------------
Arnaldo Carvalho de Melo (15):
      perf trace: Move socket_type beautifier to tools/perf/trace/beauty/
      perf callchain: Start moving away from global per thread cursors
      perf evsel: Remove symbol_conf usage
      perf symbols: Move fprintf routines to separate object file
      perf evsel: Require that callchains be resolved before calling fprintf_{sym,callchain}
      perf tools: Remove addr_location argument to sample__fprintf_callchain
      perf script: Add --max-stack knob
      perf trace: Add --max-stack knob
      perf evsel: Move fprintf methods to separate source file
      perf trace: Do not print interrupted syscalls when using --duration
      perf trace: Introduce --min-stack filter
      perf record: Export record_opts based callchain parsing helper
      perf trace: Make --(min,max}-stack imply "--call-graph dwarf"
      perf evlist: Expose perf_event_mlock_kb_in_pages() helper
      perf trace: Bump --mmap-pages when --call-graph is used by the root user

 tools/perf/Documentation/perf-script.txt           |  10 +
 tools/perf/Documentation/perf-trace.txt            |  23 +++
 tools/perf/builtin-kmem.c                          |   2 +-
 tools/perf/builtin-record.c                        |  35 ++--
 tools/perf/builtin-script.c                        |  39 ++--
 tools/perf/builtin-trace.c                         | 144 +++++++-------
 tools/perf/trace/beauty/socket_type.c              |  60 ++++++
 tools/perf/util/Build                              |   2 +
 tools/perf/util/callchain.c                        |   5 +-
 tools/perf/util/callchain.h                        |   9 +-
 tools/perf/util/evlist.c                           |  42 ++--
 tools/perf/util/evlist.h                           |   2 +
 tools/perf/util/evsel.c                            | 220 ---------------------
 tools/perf/util/evsel.h                            |  19 +-
 tools/perf/util/evsel_fprintf.c                    | 212 ++++++++++++++++++++
 tools/perf/util/hist.c                             |   2 +-
 tools/perf/util/machine.c                          |  26 +--
 tools/perf/util/machine.h                          |   4 +
 tools/perf/util/python-ext-sources                 |   1 +
 .../perf/util/scripting-engines/trace-event-perl.c |   2 +-
 .../util/scripting-engines/trace-event-python.c    |   2 +-
 tools/perf/util/symbol.c                           |  71 -------
 tools/perf/util/symbol.h                           |   5 +
 tools/perf/util/symbol_fprintf.c                   |  71 +++++++
 24 files changed, 565 insertions(+), 443 deletions(-)
 create mode 100644 tools/perf/trace/beauty/socket_type.c
 create mode 100644 tools/perf/util/evsel_fprintf.c
 create mode 100644 tools/perf/util/symbol_fprintf.c

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

* [PATCH 01/15] perf trace: Move socket_type beautifier to tools/perf/trace/beauty/
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 02/15] perf callchain: Start moving away from global per thread cursors Arnaldo Carvalho de Melo
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

To reduce the size of builtin-trace.c.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-ao91htwxdqwlwxr47gbluou1@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c            | 60 +----------------------------------
 tools/perf/trace/beauty/socket_type.c | 60 +++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 59 deletions(-)
 create mode 100644 tools/perf/trace/beauty/socket_type.c

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 8e090a785c5e..e5f0cc16bb93 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -51,18 +51,6 @@
 # define O_CLOEXEC		02000000
 #endif
 
-#ifndef SOCK_DCCP
-# define SOCK_DCCP		6
-#endif
-
-#ifndef SOCK_CLOEXEC
-# define SOCK_CLOEXEC		02000000
-#endif
-
-#ifndef SOCK_NONBLOCK
-# define SOCK_NONBLOCK		00004000
-#endif
-
 #ifndef MSG_CMSG_CLOEXEC
 # define MSG_CMSG_CLOEXEC	0x40000000
 #endif
@@ -538,53 +526,6 @@ static const char *socket_families[] = {
 };
 static DEFINE_STRARRAY(socket_families);
 
-#ifndef SOCK_TYPE_MASK
-#define SOCK_TYPE_MASK 0xf
-#endif
-
-static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size,
-						      struct syscall_arg *arg)
-{
-	size_t printed;
-	int type = arg->val,
-	    flags = type & ~SOCK_TYPE_MASK;
-
-	type &= SOCK_TYPE_MASK;
-	/*
- 	 * Can't use a strarray, MIPS may override for ABI reasons.
- 	 */
-	switch (type) {
-#define	P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
-	P_SK_TYPE(STREAM);
-	P_SK_TYPE(DGRAM);
-	P_SK_TYPE(RAW);
-	P_SK_TYPE(RDM);
-	P_SK_TYPE(SEQPACKET);
-	P_SK_TYPE(DCCP);
-	P_SK_TYPE(PACKET);
-#undef P_SK_TYPE
-	default:
-		printed = scnprintf(bf, size, "%#x", type);
-	}
-
-#define	P_SK_FLAG(n) \
-	if (flags & SOCK_##n) { \
-		printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
-		flags &= ~SOCK_##n; \
-	}
-
-	P_SK_FLAG(CLOEXEC);
-	P_SK_FLAG(NONBLOCK);
-#undef P_SK_FLAG
-
-	if (flags)
-		printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
-
-	return printed;
-}
-
-#define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
-
 #ifndef MSG_PROBE
 #define MSG_PROBE	     0x10
 #endif
@@ -951,6 +892,7 @@ static size_t syscall_arg__scnprintf_getrandom_flags(char *bf, size_t size,
 #include "trace/beauty/mmap.c"
 #include "trace/beauty/mode_t.c"
 #include "trace/beauty/sched_policy.c"
+#include "trace/beauty/socket_type.c"
 #include "trace/beauty/waitid_options.c"
 
 static struct syscall_fmt {
diff --git a/tools/perf/trace/beauty/socket_type.c b/tools/perf/trace/beauty/socket_type.c
new file mode 100644
index 000000000000..0a5ce818131c
--- /dev/null
+++ b/tools/perf/trace/beauty/socket_type.c
@@ -0,0 +1,60 @@
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#ifndef SOCK_DCCP
+# define SOCK_DCCP		6
+#endif
+
+#ifndef SOCK_CLOEXEC
+# define SOCK_CLOEXEC		02000000
+#endif
+
+#ifndef SOCK_NONBLOCK
+# define SOCK_NONBLOCK		00004000
+#endif
+
+#ifndef SOCK_TYPE_MASK
+#define SOCK_TYPE_MASK 0xf
+#endif
+
+static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, struct syscall_arg *arg)
+{
+	size_t printed;
+	int type = arg->val,
+	    flags = type & ~SOCK_TYPE_MASK;
+
+	type &= SOCK_TYPE_MASK;
+	/*
+	 * Can't use a strarray, MIPS may override for ABI reasons.
+	 */
+	switch (type) {
+#define	P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break;
+	P_SK_TYPE(STREAM);
+	P_SK_TYPE(DGRAM);
+	P_SK_TYPE(RAW);
+	P_SK_TYPE(RDM);
+	P_SK_TYPE(SEQPACKET);
+	P_SK_TYPE(DCCP);
+	P_SK_TYPE(PACKET);
+#undef P_SK_TYPE
+	default:
+		printed = scnprintf(bf, size, "%#x", type);
+	}
+
+#define	P_SK_FLAG(n) \
+	if (flags & SOCK_##n) { \
+		printed += scnprintf(bf + printed, size - printed, "|%s", #n); \
+		flags &= ~SOCK_##n; \
+	}
+
+	P_SK_FLAG(CLOEXEC);
+	P_SK_FLAG(NONBLOCK);
+#undef P_SK_FLAG
+
+	if (flags)
+		printed += scnprintf(bf + printed, size - printed, "|%#x", flags);
+
+	return printed;
+}
+
+#define SCA_SK_TYPE syscall_arg__scnprintf_socket_type
-- 
2.5.5

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

* [PATCH 02/15] perf callchain: Start moving away from global per thread cursors
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 01/15] perf trace: Move socket_type beautifier to tools/perf/trace/beauty/ Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 03/15] perf evsel: Remove symbol_conf usage Arnaldo Carvalho de Melo
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Frederic Weisbecker, Jiri Olsa, Namhyung Kim,
	Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

The recent perf_evsel__fprintf_callchain() move to evsel.c added several
new symbol requirements to the python binding, for instance:

  # perf test -v python
  16: Try 'import perf' in python, checking link problems      :
  --- start ---
  test child forked, pid 18030
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  ImportError: /tmp/build/perf/python/perf.so: undefined symbol:
  callchain_cursor
  test child finished with -1
  ---- end ----
  Try 'import perf' in python, checking link problems: FAILED!
  #

This would require linking against callchain.c to access to the global
callchain_cursor variables.

Since lots of functions already receive as a parameter a
callchain_cursor struct pointer, make that be the case for some more
function so that we can start phasing out usage of yet another global
variable.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-djko3097eyg2rn66v2qcqfvn@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-kmem.c                          |  2 +-
 tools/perf/util/callchain.c                        |  5 +++--
 tools/perf/util/callchain.h                        |  3 ++-
 tools/perf/util/evsel.c                            |  9 ++++----
 tools/perf/util/hist.c                             |  2 +-
 tools/perf/util/machine.c                          | 26 +++++++++++++---------
 tools/perf/util/machine.h                          |  4 ++++
 .../perf/util/scripting-engines/trace-event-perl.c |  2 +-
 .../util/scripting-engines/trace-event-python.c    |  2 +-
 9 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index c9cb3be47cff..58adfee230de 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -375,7 +375,7 @@ static u64 find_callsite(struct perf_evsel *evsel, struct perf_sample *sample)
 	}
 
 	al.thread = machine__findnew_thread(machine, sample->pid, sample->tid);
-	sample__resolve_callchain(sample, NULL, evsel, &al, 16);
+	sample__resolve_callchain(sample, &callchain_cursor, NULL, evsel, &al, 16);
 
 	callchain_cursor_commit(&callchain_cursor);
 	while (true) {
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 24b4bd0d7754..2b4ceaf058bb 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -788,7 +788,8 @@ int callchain_cursor_append(struct callchain_cursor *cursor,
 	return 0;
 }
 
-int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
+int sample__resolve_callchain(struct perf_sample *sample,
+			      struct callchain_cursor *cursor, struct symbol **parent,
 			      struct perf_evsel *evsel, struct addr_location *al,
 			      int max_stack)
 {
@@ -797,7 +798,7 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
 
 	if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||
 	    sort__has_parent) {
-		return thread__resolve_callchain(al->thread, evsel, sample,
+		return thread__resolve_callchain(al->thread, cursor, evsel, sample,
 						 parent, al, max_stack);
 	}
 	return 0;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index d2a9e694810c..cae5a7b1f5c8 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -212,7 +212,8 @@ struct hist_entry;
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
-int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent,
+int sample__resolve_callchain(struct perf_sample *sample,
+			      struct callchain_cursor *cursor, struct symbol **parent,
 			      struct perf_evsel *evsel, struct addr_location *al,
 			      int max_stack);
 int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *sample);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 6e86598682be..38f464a4fa04 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2349,6 +2349,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 				  FILE *fp)
 {
 	int printed = 0;
+	struct callchain_cursor cursor;
 	struct callchain_cursor_node *node;
 	int print_ip = print_opts & EVSEL__PRINT_IP;
 	int print_sym = print_opts & EVSEL__PRINT_SYM;
@@ -2362,14 +2363,14 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 	if (sample->callchain) {
 		struct addr_location node_al;
 
-		if (thread__resolve_callchain(al->thread, evsel,
+		if (thread__resolve_callchain(al->thread, &cursor, evsel,
 					      sample, NULL, NULL,
 					      stack_depth) != 0) {
 			if (verbose)
 				error("Failed to resolve callchain. Skipping\n");
 			return printed;
 		}
-		callchain_cursor_commit(&callchain_cursor);
+		callchain_cursor_commit(&cursor);
 
 		if (print_symoffset)
 			node_al = *al;
@@ -2377,7 +2378,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 		while (stack_depth) {
 			u64 addr = 0;
 
-			node = callchain_cursor_current(&callchain_cursor);
+			node = callchain_cursor_current(&cursor);
 			if (!node)
 				break;
 
@@ -2420,7 +2421,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 
 			stack_depth--;
 next:
-			callchain_cursor_advance(&callchain_cursor);
+			callchain_cursor_advance(&cursor);
 		}
 	}
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 3d34c57dfbe2..991a351a8a41 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -953,7 +953,7 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 {
 	int err, err2;
 
-	err = sample__resolve_callchain(iter->sample, &iter->parent,
+	err = sample__resolve_callchain(iter->sample, &callchain_cursor, &iter->parent,
 					iter->evsel, al, max_stack_depth);
 	if (err)
 		return err;
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 80b9b6a87990..0c4dabc69932 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1599,6 +1599,7 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
 }
 
 static int add_callchain_ip(struct thread *thread,
+			    struct callchain_cursor *cursor,
 			    struct symbol **parent,
 			    struct addr_location *root_al,
 			    u8 *cpumode,
@@ -1630,7 +1631,7 @@ static int add_callchain_ip(struct thread *thread,
 				 * It seems the callchain is corrupted.
 				 * Discard all.
 				 */
-				callchain_cursor_reset(&callchain_cursor);
+				callchain_cursor_reset(cursor);
 				return 1;
 			}
 			return 0;
@@ -1648,13 +1649,13 @@ static int add_callchain_ip(struct thread *thread,
 			/* Treat this symbol as the root,
 			   forgetting its callees. */
 			*root_al = al;
-			callchain_cursor_reset(&callchain_cursor);
+			callchain_cursor_reset(cursor);
 		}
 	}
 
 	if (symbol_conf.hide_unresolved && al.sym == NULL)
 		return 0;
-	return callchain_cursor_append(&callchain_cursor, al.addr, al.map, al.sym);
+	return callchain_cursor_append(cursor, al.addr, al.map, al.sym);
 }
 
 struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
@@ -1724,6 +1725,7 @@ static int remove_loops(struct branch_entry *l, int nr)
  * negative error code on other errors.
  */
 static int resolve_lbr_callchain_sample(struct thread *thread,
+					struct callchain_cursor *cursor,
 					struct perf_sample *sample,
 					struct symbol **parent,
 					struct addr_location *root_al,
@@ -1778,7 +1780,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
 					ip = lbr_stack->entries[0].to;
 			}
 
-			err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+			err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
 			if (err)
 				return (err < 0) ? err : 0;
 		}
@@ -1789,6 +1791,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
 }
 
 static int thread__resolve_callchain_sample(struct thread *thread,
+					    struct callchain_cursor *cursor,
 					    struct perf_evsel *evsel,
 					    struct perf_sample *sample,
 					    struct symbol **parent,
@@ -1803,10 +1806,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
 	int skip_idx = -1;
 	int first_call = 0;
 
-	callchain_cursor_reset(&callchain_cursor);
+	callchain_cursor_reset(cursor);
 
 	if (has_branch_callstack(evsel)) {
-		err = resolve_lbr_callchain_sample(thread, sample, parent,
+		err = resolve_lbr_callchain_sample(thread, cursor, sample, parent,
 						   root_al, max_stack);
 		if (err)
 			return (err < 0) ? err : 0;
@@ -1863,10 +1866,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
 		nr = remove_loops(be, nr);
 
 		for (i = 0; i < nr; i++) {
-			err = add_callchain_ip(thread, parent, root_al,
+			err = add_callchain_ip(thread, cursor, parent, root_al,
 					       NULL, be[i].to);
 			if (!err)
-				err = add_callchain_ip(thread, parent, root_al,
+				err = add_callchain_ip(thread, cursor, parent, root_al,
 						       NULL, be[i].from);
 			if (err == -EINVAL)
 				break;
@@ -1896,7 +1899,7 @@ check_calls:
 #endif
 		ip = chain->ips[j];
 
-		err = add_callchain_ip(thread, parent, root_al, &cpumode, ip);
+		err = add_callchain_ip(thread, cursor, parent, root_al, &cpumode, ip);
 
 		if (err)
 			return (err < 0) ? err : 0;
@@ -1916,13 +1919,14 @@ static int unwind_entry(struct unwind_entry *entry, void *arg)
 }
 
 int thread__resolve_callchain(struct thread *thread,
+			      struct callchain_cursor *cursor,
 			      struct perf_evsel *evsel,
 			      struct perf_sample *sample,
 			      struct symbol **parent,
 			      struct addr_location *root_al,
 			      int max_stack)
 {
-	int ret = thread__resolve_callchain_sample(thread, evsel,
+	int ret = thread__resolve_callchain_sample(thread, cursor, evsel,
 						   sample, parent,
 						   root_al, max_stack);
 	if (ret)
@@ -1938,7 +1942,7 @@ int thread__resolve_callchain(struct thread *thread,
 	    (!sample->user_stack.size))
 		return 0;
 
-	return unwind__get_entries(unwind_entry, &callchain_cursor,
+	return unwind__get_entries(unwind_entry, cursor,
 				   thread, sample, max_stack);
 
 }
diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h
index 8499db281158..382873bdc563 100644
--- a/tools/perf/util/machine.h
+++ b/tools/perf/util/machine.h
@@ -141,7 +141,11 @@ struct branch_info *sample__resolve_bstack(struct perf_sample *sample,
 					   struct addr_location *al);
 struct mem_info *sample__resolve_mem(struct perf_sample *sample,
 				     struct addr_location *al);
+
+struct callchain_cursor;
+
 int thread__resolve_callchain(struct thread *thread,
+			      struct callchain_cursor *cursor,
 			      struct perf_evsel *evsel,
 			      struct perf_sample *sample,
 			      struct symbol **parent,
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c
index 35ed00a600fb..ae1cebc307c5 100644
--- a/tools/perf/util/scripting-engines/trace-event-perl.c
+++ b/tools/perf/util/scripting-engines/trace-event-perl.c
@@ -263,7 +263,7 @@ static SV *perl_process_callchain(struct perf_sample *sample,
 	if (!symbol_conf.use_callchain || !sample->callchain)
 		goto exit;
 
-	if (thread__resolve_callchain(al->thread, evsel,
+	if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
 				      sample, NULL, NULL,
 				      PERF_MAX_STACK_DEPTH) != 0) {
 		pr_err("Failed to resolve callchain. Skipping\n");
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index fbd05242b4e5..525eb49e7ba6 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -323,7 +323,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
 	if (!symbol_conf.use_callchain || !sample->callchain)
 		goto exit;
 
-	if (thread__resolve_callchain(al->thread, evsel,
+	if (thread__resolve_callchain(al->thread, &callchain_cursor, evsel,
 				      sample, NULL, NULL,
 				      scripting_max_stack) != 0) {
 		pr_err("Failed to resolve callchain. Skipping\n");
-- 
2.5.5

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

* [PATCH 03/15] perf evsel: Remove symbol_conf usage
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 01/15] perf trace: Move socket_type beautifier to tools/perf/trace/beauty/ Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 02/15] perf callchain: Start moving away from global per thread cursors Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 04/15] perf symbols: Move fprintf routines to separate object file Arnaldo Carvalho de Melo
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

  # perf test -v python
  16: Try 'import perf' in python, checking link problems      :
  --- start ---
  test child forked, pid 672
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  ImportError: /tmp/build/perf/python/perf.so: undefined symbol:
  symbol_conf
  test child finished with -1
  ---- end ----
  Try 'import perf' in python, checking link problems: FAILED!
  #

To fix it just pass a parameter to perf_evsel__fprintf_sym telling if
callchains should be printed.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-comrsr20bsnr8bg0n6rfwv12@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-script.c | 2 ++
 tools/perf/util/evsel.c     | 6 +++---
 tools/perf/util/evsel.h     | 4 ++--
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 838c0bc38105..717ba0215234 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -580,6 +580,7 @@ static void print_sample_bts(struct perf_sample *sample,
 			}
 		}
 		perf_evsel__fprintf_sym(evsel, sample, al, 0, print_opts,
+					symbol_conf.use_callchain,
 					scripting_max_stack, stdout);
 	}
 
@@ -790,6 +791,7 @@ static void process_event(struct perf_script *script,
 
 		perf_evsel__fprintf_sym(evsel, sample, al, 0,
 					output[attr->type].print_ip_opts,
+					symbol_conf.use_callchain,
 					scripting_max_stack, stdout);
 	}
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 38f464a4fa04..60bba67e6959 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2430,8 +2430,8 @@ next:
 
 int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample,
 			    struct addr_location *al, int left_alignment,
-			    unsigned int print_opts, unsigned int stack_depth,
-			    FILE *fp)
+			    unsigned int print_opts, bool print_callchain,
+			    unsigned int stack_depth, FILE *fp)
 {
 	int printed = 0;
 	int print_ip = print_opts & EVSEL__PRINT_IP;
@@ -2441,7 +2441,7 @@ int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample
 	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
 	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 
-	if (symbol_conf.use_callchain && sample->callchain) {
+	if (print_callchain && sample->callchain) {
 		printed += perf_evsel__fprintf_callchain(evsel, sample, al, left_alignment,
 							 print_opts, stack_depth, fp);
 	} else if (!(al->sym && al->sym->ignore)) {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 36edd3c91d5c..013f3615730b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -403,8 +403,8 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel,
 
 int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample,
 			    struct addr_location *al, int left_alignment,
-			    unsigned int print_opts, unsigned int stack_depth,
-			    FILE *fp);
+			    unsigned int print_opts, bool print_callchain,
+			    unsigned int stack_depth, FILE *fp);
 
 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
 			  char *msg, size_t msgsize);
-- 
2.5.5

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

* [PATCH 04/15] perf symbols: Move fprintf routines to separate object file
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (2 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 03/15] perf evsel: Remove symbol_conf usage Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 05/15] perf evsel: Require that callchains be resolved before calling fprintf_{sym,callchain} Arnaldo Carvalho de Melo
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

To disentangle symbol printing from all the code related to symbol
tables, resolution of addresses to symbols, etc.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-eik9g3hbtdc7ddv57f1d4v3p@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/Build              |  1 +
 tools/perf/util/python-ext-sources |  1 +
 tools/perf/util/symbol.c           | 71 --------------------------------------
 tools/perf/util/symbol.h           |  5 +++
 tools/perf/util/symbol_fprintf.c   | 71 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 78 insertions(+), 71 deletions(-)
 create mode 100644 tools/perf/util/symbol_fprintf.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index ea4ac03c1ec8..61021334e958 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -29,6 +29,7 @@ libperf-y += usage.o
 libperf-y += wrapper.o
 libperf-y += dso.o
 libperf-y += symbol.o
+libperf-y += symbol_fprintf.o
 libperf-y += color.o
 libperf-y += header.o
 libperf-y += callchain.o
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 8162ba0e2e57..36c6862119e3 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -23,3 +23,4 @@ util/strlist.c
 util/trace-event.c
 ../lib/rbtree.c
 util/string.c
+util/symbol_fprintf.c
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index bb162ee433c6..a36823c3b7c0 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -255,57 +255,6 @@ void symbol__delete(struct symbol *sym)
 	free(((void *)sym) - symbol_conf.priv_size);
 }
 
-size_t symbol__fprintf(struct symbol *sym, FILE *fp)
-{
-	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
-		       sym->start, sym->end,
-		       sym->binding == STB_GLOBAL ? 'g' :
-		       sym->binding == STB_LOCAL  ? 'l' : 'w',
-		       sym->name);
-}
-
-size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
-				      const struct addr_location *al,
-				      bool unknown_as_addr, FILE *fp)
-{
-	unsigned long offset;
-	size_t length;
-
-	if (sym && sym->name) {
-		length = fprintf(fp, "%s", sym->name);
-		if (al) {
-			if (al->addr < sym->end)
-				offset = al->addr - sym->start;
-			else
-				offset = al->addr - al->map->start - sym->start;
-			length += fprintf(fp, "+0x%lx", offset);
-		}
-		return length;
-	} else if (al && unknown_as_addr)
-		return fprintf(fp, "[%#" PRIx64 "]", al->addr);
-	else
-		return fprintf(fp, "[unknown]");
-}
-
-size_t symbol__fprintf_symname_offs(const struct symbol *sym,
-				    const struct addr_location *al,
-				    FILE *fp)
-{
-	return __symbol__fprintf_symname_offs(sym, al, false, fp);
-}
-
-size_t __symbol__fprintf_symname(const struct symbol *sym,
-				 const struct addr_location *al,
-				 bool unknown_as_addr, FILE *fp)
-{
-	return __symbol__fprintf_symname_offs(sym, al, unknown_as_addr, fp);
-}
-
-size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
-{
-	return __symbol__fprintf_symname_offs(sym, NULL, false, fp);
-}
-
 void symbols__delete(struct rb_root *symbols)
 {
 	struct symbol *pos;
@@ -381,11 +330,6 @@ static struct symbol *symbols__next(struct symbol *sym)
 	return NULL;
 }
 
-struct symbol_name_rb_node {
-	struct rb_node	rb_node;
-	struct symbol	sym;
-};
-
 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
 {
 	struct rb_node **p = &symbols->rb_node;
@@ -514,21 +458,6 @@ void dso__sort_by_name(struct dso *dso, enum map_type type)
 				     &dso->symbols[type]);
 }
 
-size_t dso__fprintf_symbols_by_name(struct dso *dso,
-				    enum map_type type, FILE *fp)
-{
-	size_t ret = 0;
-	struct rb_node *nd;
-	struct symbol_name_rb_node *pos;
-
-	for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
-		pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
-		fprintf(fp, "%s\n", pos->sym.name);
-	}
-
-	return ret;
-}
-
 int modules__parse(const char *filename, void *arg,
 		   int (*process_module)(void *arg, const char *name,
 					 u64 start))
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index e2562568418d..1da7b101bc7f 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -140,6 +140,11 @@ struct symbol_conf {
 
 extern struct symbol_conf symbol_conf;
 
+struct symbol_name_rb_node {
+	struct rb_node	rb_node;
+	struct symbol	sym;
+};
+
 static inline int __symbol__join_symfs(char *bf, size_t size, const char *path)
 {
 	return path__join(bf, size, symbol_conf.symfs, path);
diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c
new file mode 100644
index 000000000000..a680bdaa65dc
--- /dev/null
+++ b/tools/perf/util/symbol_fprintf.c
@@ -0,0 +1,71 @@
+#include <elf.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+#include "symbol.h"
+
+size_t symbol__fprintf(struct symbol *sym, FILE *fp)
+{
+	return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
+		       sym->start, sym->end,
+		       sym->binding == STB_GLOBAL ? 'g' :
+		       sym->binding == STB_LOCAL  ? 'l' : 'w',
+		       sym->name);
+}
+
+size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
+				      const struct addr_location *al,
+				      bool unknown_as_addr, FILE *fp)
+{
+	unsigned long offset;
+	size_t length;
+
+	if (sym && sym->name) {
+		length = fprintf(fp, "%s", sym->name);
+		if (al) {
+			if (al->addr < sym->end)
+				offset = al->addr - sym->start;
+			else
+				offset = al->addr - al->map->start - sym->start;
+			length += fprintf(fp, "+0x%lx", offset);
+		}
+		return length;
+	} else if (al && unknown_as_addr)
+		return fprintf(fp, "[%#" PRIx64 "]", al->addr);
+	else
+		return fprintf(fp, "[unknown]");
+}
+
+size_t symbol__fprintf_symname_offs(const struct symbol *sym,
+				    const struct addr_location *al,
+				    FILE *fp)
+{
+	return __symbol__fprintf_symname_offs(sym, al, false, fp);
+}
+
+size_t __symbol__fprintf_symname(const struct symbol *sym,
+				 const struct addr_location *al,
+				 bool unknown_as_addr, FILE *fp)
+{
+	return __symbol__fprintf_symname_offs(sym, al, unknown_as_addr, fp);
+}
+
+size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
+{
+	return __symbol__fprintf_symname_offs(sym, NULL, false, fp);
+}
+
+size_t dso__fprintf_symbols_by_name(struct dso *dso,
+				    enum map_type type, FILE *fp)
+{
+	size_t ret = 0;
+	struct rb_node *nd;
+	struct symbol_name_rb_node *pos;
+
+	for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
+		pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
+		fprintf(fp, "%s\n", pos->sym.name);
+	}
+
+	return ret;
+}
-- 
2.5.5

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

* [PATCH 05/15] perf evsel: Require that callchains be resolved before calling fprintf_{sym,callchain}
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (3 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 04/15] perf symbols: Move fprintf routines to separate object file Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 06/15] perf tools: Remove addr_location argument to sample__fprintf_callchain Arnaldo Carvalho de Melo
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

This way the print routine merely does printing, not requiring access to
the resolving machinery, which helps disentangling the object files and
easing creating subsets with a limited functionality set.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-2ti2jbra8fypdfawwwm3aee3@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-script.c | 36 ++++++++++++++++++++----------------
 tools/perf/builtin-trace.c  |  8 +++++---
 tools/perf/util/evsel.c     | 39 ++++++++++++++-------------------------
 tools/perf/util/evsel.h     | 19 +++++++++----------
 4 files changed, 48 insertions(+), 54 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 717ba0215234..875d84e7ba5b 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -569,19 +569,23 @@ static void print_sample_bts(struct perf_sample *sample,
 	/* print branch_from information */
 	if (PRINT_FIELD(IP)) {
 		unsigned int print_opts = output[attr->type].print_ip_opts;
+		struct callchain_cursor *cursor = NULL, cursor_callchain;
 
-		if (symbol_conf.use_callchain && sample->callchain) {
-			printf("\n");
-		} else {
-			printf(" ");
+		if (symbol_conf.use_callchain && sample->callchain &&
+		    thread__resolve_callchain(al->thread, &cursor_callchain, evsel,
+					      sample, NULL, NULL, scripting_max_stack) == 0)
+			cursor = &cursor_callchain;
+
+		if (cursor == NULL) {
+			putchar(' ');
 			if (print_opts & EVSEL__PRINT_SRCLINE) {
 				print_srcline_last = true;
 				print_opts &= ~EVSEL__PRINT_SRCLINE;
 			}
-		}
-		perf_evsel__fprintf_sym(evsel, sample, al, 0, print_opts,
-					symbol_conf.use_callchain,
-					scripting_max_stack, stdout);
+		} else
+			putchar('\n');
+
+		sample__fprintf_sym(sample, al, 0, print_opts, cursor, stdout);
 	}
 
 	/* print branch_to information */
@@ -784,15 +788,15 @@ static void process_event(struct perf_script *script,
 		printf("%16" PRIu64, sample->weight);
 
 	if (PRINT_FIELD(IP)) {
-		if (!symbol_conf.use_callchain)
-			printf(" ");
-		else
-			printf("\n");
+		struct callchain_cursor *cursor = NULL, cursor_callchain;
+
+		if (symbol_conf.use_callchain &&
+		    thread__resolve_callchain(al->thread, &cursor_callchain, evsel,
+					      sample, NULL, NULL, scripting_max_stack) == 0)
+			cursor = &cursor_callchain;
 
-		perf_evsel__fprintf_sym(evsel, sample, al, 0,
-					output[attr->type].print_ip_opts,
-					symbol_conf.use_callchain,
-					scripting_max_stack, stdout);
+		putchar(cursor ? '\n' : ' ');
+		sample__fprintf_sym(sample, al, 0, output[attr->type].print_ip_opts, cursor, stdout);
 	}
 
 	if (PRINT_FIELD(IREGS))
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index e5f0cc16bb93..0e2a82bda22f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1890,14 +1890,16 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_evsel *evse
 	if (sample->callchain == NULL)
 		return 0;
 
-	if (machine__resolve(trace->host, &al, sample) < 0) {
+	if (machine__resolve(trace->host, &al, sample) < 0 ||
+	    thread__resolve_callchain(al.thread, &callchain_cursor, evsel,
+				      sample, NULL, NULL, scripting_max_stack)) {
 		pr_err("Problem processing %s callchain, skipping...\n",
 			perf_evsel__name(evsel));
 		return 0;
 	}
 
-	return perf_evsel__fprintf_callchain(evsel, sample, &al, 38, print_opts,
-					     scripting_max_stack, trace->output);
+	return sample__fprintf_callchain(sample, &al, 38, print_opts,
+					 &callchain_cursor, trace->output);
 }
 
 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 60bba67e6959..35c5a5282239 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2343,13 +2343,12 @@ out:
 	return ++printed;
 }
 
-int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *sample,
-				  struct addr_location *al, int left_alignment,
-				  unsigned int print_opts, unsigned int stack_depth,
-				  FILE *fp)
+int sample__fprintf_callchain(struct perf_sample *sample,
+			      struct addr_location *al, int left_alignment,
+			      unsigned int print_opts, struct callchain_cursor *cursor,
+			      FILE *fp)
 {
 	int printed = 0;
-	struct callchain_cursor cursor;
 	struct callchain_cursor_node *node;
 	int print_ip = print_opts & EVSEL__PRINT_IP;
 	int print_sym = print_opts & EVSEL__PRINT_SYM;
@@ -2363,22 +2362,15 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 	if (sample->callchain) {
 		struct addr_location node_al;
 
-		if (thread__resolve_callchain(al->thread, &cursor, evsel,
-					      sample, NULL, NULL,
-					      stack_depth) != 0) {
-			if (verbose)
-				error("Failed to resolve callchain. Skipping\n");
-			return printed;
-		}
-		callchain_cursor_commit(&cursor);
+		callchain_cursor_commit(cursor);
 
 		if (print_symoffset)
 			node_al = *al;
 
-		while (stack_depth) {
+		while (1) {
 			u64 addr = 0;
 
-			node = callchain_cursor_current(&cursor);
+			node = callchain_cursor_current(cursor);
 			if (!node)
 				break;
 
@@ -2418,20 +2410,17 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 
 			if (!print_oneline)
 				printed += fprintf(fp, "\n");
-
-			stack_depth--;
 next:
-			callchain_cursor_advance(&cursor);
+			callchain_cursor_advance(cursor);
 		}
 	}
 
 	return printed;
 }
 
-int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample,
-			    struct addr_location *al, int left_alignment,
-			    unsigned int print_opts, bool print_callchain,
-			    unsigned int stack_depth, FILE *fp)
+int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
+			int left_alignment, unsigned int print_opts,
+			struct callchain_cursor *cursor, FILE *fp)
 {
 	int printed = 0;
 	int print_ip = print_opts & EVSEL__PRINT_IP;
@@ -2441,9 +2430,9 @@ int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample
 	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
 	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 
-	if (print_callchain && sample->callchain) {
-		printed += perf_evsel__fprintf_callchain(evsel, sample, al, left_alignment,
-							 print_opts, stack_depth, fp);
+	if (cursor != NULL) {
+		printed += sample__fprintf_callchain(sample, al, left_alignment,
+						     print_opts, cursor, fp);
 	} else if (!(al->sym && al->sym->ignore)) {
 		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 013f3615730b..abadfea1dbaa 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -395,16 +395,15 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
 #define EVSEL__PRINT_SRCLINE		(1<<5)
 #define EVSEL__PRINT_UNKNOWN_AS_ADDR	(1<<6)
 
-int perf_evsel__fprintf_callchain(struct perf_evsel *evsel,
-				  struct perf_sample *sample,
-				  struct addr_location *al, int left_alignment,
-				  unsigned int print_opts,
-				  unsigned int stack_depth, FILE *fp);
-
-int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample,
-			    struct addr_location *al, int left_alignment,
-			    unsigned int print_opts, bool print_callchain,
-			    unsigned int stack_depth, FILE *fp);
+struct callchain_cursor;
+
+int sample__fprintf_callchain(struct perf_sample *sample, struct addr_location *al,
+			      int left_alignment, unsigned int print_opts,
+			      struct callchain_cursor *cursor, FILE *fp);
+
+int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
+			int left_alignment, unsigned int print_opts,
+			struct callchain_cursor *cursor, FILE *fp);
 
 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
 			  char *msg, size_t msgsize);
-- 
2.5.5

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

* [PATCH 06/15] perf tools: Remove addr_location argument to sample__fprintf_callchain
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (4 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 05/15] perf evsel: Require that callchains be resolved before calling fprintf_{sym,callchain} Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 07/15] perf script: Add --max-stack knob Arnaldo Carvalho de Melo
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Not used at all, nuke it.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-jf2w8ce8nl3wso3vuodg5jci@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 3 +--
 tools/perf/util/evsel.c    | 8 ++------
 tools/perf/util/evsel.h    | 4 ++--
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0e2a82bda22f..5e5a95e34a53 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1898,8 +1898,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_evsel *evse
 		return 0;
 	}
 
-	return sample__fprintf_callchain(sample, &al, 38, print_opts,
-					 &callchain_cursor, trace->output);
+	return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output);
 }
 
 static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 35c5a5282239..060f619dea88 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2343,8 +2343,7 @@ out:
 	return ++printed;
 }
 
-int sample__fprintf_callchain(struct perf_sample *sample,
-			      struct addr_location *al, int left_alignment,
+int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
 			      unsigned int print_opts, struct callchain_cursor *cursor,
 			      FILE *fp)
 {
@@ -2364,9 +2363,6 @@ int sample__fprintf_callchain(struct perf_sample *sample,
 
 		callchain_cursor_commit(cursor);
 
-		if (print_symoffset)
-			node_al = *al;
-
 		while (1) {
 			u64 addr = 0;
 
@@ -2431,7 +2427,7 @@ int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
 	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
 
 	if (cursor != NULL) {
-		printed += sample__fprintf_callchain(sample, al, left_alignment,
+		printed += sample__fprintf_callchain(sample, left_alignment,
 						     print_opts, cursor, fp);
 	} else if (!(al->sym && al->sym->ignore)) {
 		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index abadfea1dbaa..b993218744d4 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -397,8 +397,8 @@ int perf_evsel__fprintf(struct perf_evsel *evsel,
 
 struct callchain_cursor;
 
-int sample__fprintf_callchain(struct perf_sample *sample, struct addr_location *al,
-			      int left_alignment, unsigned int print_opts,
+int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
+			      unsigned int print_opts,
 			      struct callchain_cursor *cursor, FILE *fp);
 
 int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
-- 
2.5.5

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

* [PATCH 07/15] perf script: Add --max-stack knob
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (5 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 06/15] perf tools: Remove addr_location argument to sample__fprintf_callchain Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 08/15] perf trace: " Arnaldo Carvalho de Melo
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Works just like with 'perf report'. In some cases we may want to have
more than 127 entries, the default maximum.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-mqkz2p5ok2978gztb0vsnocc@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-script.txt | 10 ++++++++++
 tools/perf/builtin-script.c              |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 22ef3933342a..4fc44c75263f 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -259,6 +259,16 @@ include::itrace.txt[]
 --full-source-path::
 	Show the full path for source files for srcline output.
 
+--max-stack::
+        Set the stack depth limit when parsing the callchain, anything
+        beyond the specified depth will be ignored. This is a trade-off
+        between information loss and faster processing especially for
+        workloads that can have a very long callchain stack.
+        Note that when using the --itrace option the synthesized callchain size
+        will override this value if the synthesized callchain size is bigger.
+
+        Default: 127
+
 --ns::
 	Use 9 decimal places when displaying time (i.e. show the nanoseconds)
 
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 875d84e7ba5b..0e93282b405e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -22,6 +22,7 @@
 #include "util/thread_map.h"
 #include "util/stat.h"
 #include <linux/bitmap.h>
+#include <linux/stringify.h>
 #include "asm/bug.h"
 #include "util/mem-events.h"
 
@@ -2027,6 +2028,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 		   "only consider symbols in these pids"),
 	OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]",
 		   "only consider symbols in these tids"),
+	OPT_UINTEGER(0, "max-stack", &scripting_max_stack,
+		     "Set the maximum stack depth when parsing the callchain, "
+		     "anything beyond the specified depth will be ignored. "
+		     "Default: " __stringify(PERF_MAX_STACK_DEPTH)),
 	OPT_BOOLEAN('I', "show-info", &show_full_info,
 		    "display extended information from perf.data file"),
 	OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
-- 
2.5.5

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

* [PATCH 08/15] perf trace: Add --max-stack knob
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (6 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 07/15] perf script: Add --max-stack knob Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 09/15] perf evsel: Move fprintf methods to separate source file Arnaldo Carvalho de Melo
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Similar to the one in the other tools (report, script, top).

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-lh7kk5a5t3erwxw31ah0cgar@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt | 9 +++++++++
 tools/perf/builtin-trace.c              | 9 ++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 1bbcf305d233..2ee0c4fee18d 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -129,6 +129,15 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
 --event::
 	Trace other events, see 'perf list' for a complete list.
 
+--max-stack::
+        Set the stack depth limit when parsing the callchain, anything
+        beyond the specified depth will be ignored. Note that at this point
+        this is just about the presentation part, i.e. the kernel is still
+        not limiting, the overhead of callchains needs to be set via the
+        knobs in --call-graph dwarf.
+
+        Default: 127
+
 --proc-map-timeout::
 	When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
 	because the file may be huge. A time out is needed in such cases.
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 5e5a95e34a53..39a158923acf 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -46,6 +46,7 @@
 #include <linux/audit.h>
 #include <sys/ptrace.h>
 #include <linux/random.h>
+#include <linux/stringify.h>
 
 #ifndef O_CLOEXEC
 # define O_CLOEXEC		02000000
@@ -106,6 +107,7 @@ struct trace {
 		u64		vfs_getname,
 				proc_getname;
 	} stats;
+	unsigned int		max_stack;
 	bool			not_ev_qualifier;
 	bool			live;
 	bool			full_time;
@@ -1892,7 +1894,7 @@ static int trace__fprintf_callchain(struct trace *trace, struct perf_evsel *evse
 
 	if (machine__resolve(trace->host, &al, sample) < 0 ||
 	    thread__resolve_callchain(al.thread, &callchain_cursor, evsel,
-				      sample, NULL, NULL, scripting_max_stack)) {
+				      sample, NULL, NULL, trace->max_stack)) {
 		pr_err("Problem processing %s callchain, skipping...\n",
 			perf_evsel__name(evsel));
 		return 0;
@@ -3029,6 +3031,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		.show_comm = true,
 		.trace_syscalls = true,
 		.kernel_syscallchains = false,
+		.max_stack = PERF_MAX_STACK_DEPTH,
 	};
 	const char *output_name = NULL;
 	const char *ev_qualifier_str = NULL;
@@ -3079,6 +3082,10 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		     &record_parse_callchain_opt),
 	OPT_BOOLEAN(0, "kernel-syscall-graph", &trace.kernel_syscallchains,
 		    "Show the kernel callchains on the syscall exit path"),
+	OPT_UINTEGER(0, "max-stack", &trace.max_stack,
+		     "Set the maximum stack depth when parsing the callchain, "
+		     "anything beyond the specified depth will be ignored. "
+		     "Default: " __stringify(PERF_MAX_STACK_DEPTH)),
 	OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
 			"per thread proc mmap processing timeout in ms"),
 	OPT_END()
-- 
2.5.5

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

* [PATCH 09/15] perf evsel: Move fprintf methods to separate source file
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (7 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 08/15] perf trace: " Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 10/15] perf trace: Do not print interrupted syscalls when using --duration Arnaldo Carvalho de Melo
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

They still use functions that would drag more stuff to the python
binding, where these fprintf methods are not used, so separate it.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-xfp0mgq3hh3px61di6ixi1jk@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/Build           |   1 +
 tools/perf/util/evsel.c         | 206 --------------------------------------
 tools/perf/util/evsel_fprintf.c | 212 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 213 insertions(+), 206 deletions(-)
 create mode 100644 tools/perf/util/evsel_fprintf.c

diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 61021334e958..85a9ab62e23f 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -8,6 +8,7 @@ libperf-y += env.o
 libperf-y += event.o
 libperf-y += evlist.o
 libperf-y += evsel.o
+libperf-y += evsel_fprintf.o
 libperf-y += find_bit.o
 libperf-y += kallsyms.o
 libperf-y += levenshtein.o
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 060f619dea88..545bb3f0b2b0 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2254,212 +2254,6 @@ u64 perf_evsel__intval(struct perf_evsel *evsel, struct perf_sample *sample,
 	return 0;
 }
 
-static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
-{
-	va_list args;
-	int ret = 0;
-
-	if (!*first) {
-		ret += fprintf(fp, ",");
-	} else {
-		ret += fprintf(fp, ":");
-		*first = false;
-	}
-
-	va_start(args, fmt);
-	ret += vfprintf(fp, fmt, args);
-	va_end(args);
-	return ret;
-}
-
-static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
-{
-	return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
-}
-
-int perf_evsel__fprintf(struct perf_evsel *evsel,
-			struct perf_attr_details *details, FILE *fp)
-{
-	bool first = true;
-	int printed = 0;
-
-	if (details->event_group) {
-		struct perf_evsel *pos;
-
-		if (!perf_evsel__is_group_leader(evsel))
-			return 0;
-
-		if (evsel->nr_members > 1)
-			printed += fprintf(fp, "%s{", evsel->group_name ?: "");
-
-		printed += fprintf(fp, "%s", perf_evsel__name(evsel));
-		for_each_group_member(pos, evsel)
-			printed += fprintf(fp, ",%s", perf_evsel__name(pos));
-
-		if (evsel->nr_members > 1)
-			printed += fprintf(fp, "}");
-		goto out;
-	}
-
-	printed += fprintf(fp, "%s", perf_evsel__name(evsel));
-
-	if (details->verbose) {
-		printed += perf_event_attr__fprintf(fp, &evsel->attr,
-						    __print_attr__fprintf, &first);
-	} else if (details->freq) {
-		const char *term = "sample_freq";
-
-		if (!evsel->attr.freq)
-			term = "sample_period";
-
-		printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
-					 term, (u64)evsel->attr.sample_freq);
-	}
-
-	if (details->trace_fields) {
-		struct format_field *field;
-
-		if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
-			printed += comma_fprintf(fp, &first, " (not a tracepoint)");
-			goto out;
-		}
-
-		field = evsel->tp_format->format.fields;
-		if (field == NULL) {
-			printed += comma_fprintf(fp, &first, " (no trace field)");
-			goto out;
-		}
-
-		printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
-
-		field = field->next;
-		while (field) {
-			printed += comma_fprintf(fp, &first, "%s", field->name);
-			field = field->next;
-		}
-	}
-out:
-	fputc('\n', fp);
-	return ++printed;
-}
-
-int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
-			      unsigned int print_opts, struct callchain_cursor *cursor,
-			      FILE *fp)
-{
-	int printed = 0;
-	struct callchain_cursor_node *node;
-	int print_ip = print_opts & EVSEL__PRINT_IP;
-	int print_sym = print_opts & EVSEL__PRINT_SYM;
-	int print_dso = print_opts & EVSEL__PRINT_DSO;
-	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
-	int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
-	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
-	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
-	char s = print_oneline ? ' ' : '\t';
-
-	if (sample->callchain) {
-		struct addr_location node_al;
-
-		callchain_cursor_commit(cursor);
-
-		while (1) {
-			u64 addr = 0;
-
-			node = callchain_cursor_current(cursor);
-			if (!node)
-				break;
-
-			if (node->sym && node->sym->ignore)
-				goto next;
-
-			printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
-
-			if (print_ip)
-				printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
-
-			if (node->map)
-				addr = node->map->map_ip(node->map, node->ip);
-
-			if (print_sym) {
-				printed += fprintf(fp, " ");
-				node_al.addr = addr;
-				node_al.map  = node->map;
-
-				if (print_symoffset) {
-					printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
-										  print_unknown_as_addr, fp);
-				} else {
-					printed += __symbol__fprintf_symname(node->sym, &node_al,
-									     print_unknown_as_addr, fp);
-				}
-			}
-
-			if (print_dso) {
-				printed += fprintf(fp, " (");
-				printed += map__fprintf_dsoname(node->map, fp);
-				printed += fprintf(fp, ")");
-			}
-
-			if (print_srcline)
-				printed += map__fprintf_srcline(node->map, addr, "\n  ", fp);
-
-			if (!print_oneline)
-				printed += fprintf(fp, "\n");
-next:
-			callchain_cursor_advance(cursor);
-		}
-	}
-
-	return printed;
-}
-
-int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
-			int left_alignment, unsigned int print_opts,
-			struct callchain_cursor *cursor, FILE *fp)
-{
-	int printed = 0;
-	int print_ip = print_opts & EVSEL__PRINT_IP;
-	int print_sym = print_opts & EVSEL__PRINT_SYM;
-	int print_dso = print_opts & EVSEL__PRINT_DSO;
-	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
-	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
-	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
-
-	if (cursor != NULL) {
-		printed += sample__fprintf_callchain(sample, left_alignment,
-						     print_opts, cursor, fp);
-	} else if (!(al->sym && al->sym->ignore)) {
-		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
-
-		if (print_ip)
-			printed += fprintf(fp, "%16" PRIx64, sample->ip);
-
-		if (print_sym) {
-			printed += fprintf(fp, " ");
-			if (print_symoffset) {
-				printed += __symbol__fprintf_symname_offs(al->sym, al,
-									  print_unknown_as_addr, fp);
-			} else {
-				printed += __symbol__fprintf_symname(al->sym, al,
-								     print_unknown_as_addr, fp);
-			}
-		}
-
-		if (print_dso) {
-			printed += fprintf(fp, " (");
-			printed += map__fprintf_dsoname(al->map, fp);
-			printed += fprintf(fp, ")");
-		}
-
-		if (print_srcline)
-			printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
-	}
-
-	return printed;
-}
-
-
 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
 			  char *msg, size_t msgsize)
 {
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
new file mode 100644
index 000000000000..3674e77ad640
--- /dev/null
+++ b/tools/perf/util/evsel_fprintf.c
@@ -0,0 +1,212 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <traceevent/event-parse.h>
+#include "evsel.h"
+#include "callchain.h"
+#include "map.h"
+#include "symbol.h"
+
+static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...)
+{
+	va_list args;
+	int ret = 0;
+
+	if (!*first) {
+		ret += fprintf(fp, ",");
+	} else {
+		ret += fprintf(fp, ":");
+		*first = false;
+	}
+
+	va_start(args, fmt);
+	ret += vfprintf(fp, fmt, args);
+	va_end(args);
+	return ret;
+}
+
+static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv)
+{
+	return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val);
+}
+
+int perf_evsel__fprintf(struct perf_evsel *evsel,
+			struct perf_attr_details *details, FILE *fp)
+{
+	bool first = true;
+	int printed = 0;
+
+	if (details->event_group) {
+		struct perf_evsel *pos;
+
+		if (!perf_evsel__is_group_leader(evsel))
+			return 0;
+
+		if (evsel->nr_members > 1)
+			printed += fprintf(fp, "%s{", evsel->group_name ?: "");
+
+		printed += fprintf(fp, "%s", perf_evsel__name(evsel));
+		for_each_group_member(pos, evsel)
+			printed += fprintf(fp, ",%s", perf_evsel__name(pos));
+
+		if (evsel->nr_members > 1)
+			printed += fprintf(fp, "}");
+		goto out;
+	}
+
+	printed += fprintf(fp, "%s", perf_evsel__name(evsel));
+
+	if (details->verbose) {
+		printed += perf_event_attr__fprintf(fp, &evsel->attr,
+						    __print_attr__fprintf, &first);
+	} else if (details->freq) {
+		const char *term = "sample_freq";
+
+		if (!evsel->attr.freq)
+			term = "sample_period";
+
+		printed += comma_fprintf(fp, &first, " %s=%" PRIu64,
+					 term, (u64)evsel->attr.sample_freq);
+	}
+
+	if (details->trace_fields) {
+		struct format_field *field;
+
+		if (evsel->attr.type != PERF_TYPE_TRACEPOINT) {
+			printed += comma_fprintf(fp, &first, " (not a tracepoint)");
+			goto out;
+		}
+
+		field = evsel->tp_format->format.fields;
+		if (field == NULL) {
+			printed += comma_fprintf(fp, &first, " (no trace field)");
+			goto out;
+		}
+
+		printed += comma_fprintf(fp, &first, " trace_fields: %s", field->name);
+
+		field = field->next;
+		while (field) {
+			printed += comma_fprintf(fp, &first, "%s", field->name);
+			field = field->next;
+		}
+	}
+out:
+	fputc('\n', fp);
+	return ++printed;
+}
+
+int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
+			      unsigned int print_opts, struct callchain_cursor *cursor,
+			      FILE *fp)
+{
+	int printed = 0;
+	struct callchain_cursor_node *node;
+	int print_ip = print_opts & EVSEL__PRINT_IP;
+	int print_sym = print_opts & EVSEL__PRINT_SYM;
+	int print_dso = print_opts & EVSEL__PRINT_DSO;
+	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
+	int print_oneline = print_opts & EVSEL__PRINT_ONELINE;
+	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
+	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
+	char s = print_oneline ? ' ' : '\t';
+
+	if (sample->callchain) {
+		struct addr_location node_al;
+
+		callchain_cursor_commit(cursor);
+
+		while (1) {
+			u64 addr = 0;
+
+			node = callchain_cursor_current(cursor);
+			if (!node)
+				break;
+
+			if (node->sym && node->sym->ignore)
+				goto next;
+
+			printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
+
+			if (print_ip)
+				printed += fprintf(fp, "%c%16" PRIx64, s, node->ip);
+
+			if (node->map)
+				addr = node->map->map_ip(node->map, node->ip);
+
+			if (print_sym) {
+				printed += fprintf(fp, " ");
+				node_al.addr = addr;
+				node_al.map  = node->map;
+
+				if (print_symoffset) {
+					printed += __symbol__fprintf_symname_offs(node->sym, &node_al,
+										  print_unknown_as_addr, fp);
+				} else {
+					printed += __symbol__fprintf_symname(node->sym, &node_al,
+									     print_unknown_as_addr, fp);
+				}
+			}
+
+			if (print_dso) {
+				printed += fprintf(fp, " (");
+				printed += map__fprintf_dsoname(node->map, fp);
+				printed += fprintf(fp, ")");
+			}
+
+			if (print_srcline)
+				printed += map__fprintf_srcline(node->map, addr, "\n  ", fp);
+
+			if (!print_oneline)
+				printed += fprintf(fp, "\n");
+next:
+			callchain_cursor_advance(cursor);
+		}
+	}
+
+	return printed;
+}
+
+int sample__fprintf_sym(struct perf_sample *sample, struct addr_location *al,
+			int left_alignment, unsigned int print_opts,
+			struct callchain_cursor *cursor, FILE *fp)
+{
+	int printed = 0;
+	int print_ip = print_opts & EVSEL__PRINT_IP;
+	int print_sym = print_opts & EVSEL__PRINT_SYM;
+	int print_dso = print_opts & EVSEL__PRINT_DSO;
+	int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET;
+	int print_srcline = print_opts & EVSEL__PRINT_SRCLINE;
+	int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR;
+
+	if (cursor != NULL) {
+		printed += sample__fprintf_callchain(sample, left_alignment,
+						     print_opts, cursor, fp);
+	} else if (!(al->sym && al->sym->ignore)) {
+		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
+
+		if (print_ip)
+			printed += fprintf(fp, "%16" PRIx64, sample->ip);
+
+		if (print_sym) {
+			printed += fprintf(fp, " ");
+			if (print_symoffset) {
+				printed += __symbol__fprintf_symname_offs(al->sym, al,
+									  print_unknown_as_addr, fp);
+			} else {
+				printed += __symbol__fprintf_symname(al->sym, al,
+								     print_unknown_as_addr, fp);
+			}
+		}
+
+		if (print_dso) {
+			printed += fprintf(fp, " (");
+			printed += map__fprintf_dsoname(al->map, fp);
+			printed += fprintf(fp, ")");
+		}
+
+		if (print_srcline)
+			printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
+	}
+
+	return printed;
+}
-- 
2.5.5

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

* [PATCH 10/15] perf trace: Do not print interrupted syscalls when using --duration
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (8 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 09/15] perf evsel: Move fprintf methods to separate source file Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 11/15] perf trace: Introduce --min-stack filter Arnaldo Carvalho de Melo
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

With multiple threads, e.g. a system wide trace session, and one syscall is
midway in a thread and another thread starts another syscall we must print the
start of the interrupted syscall followed by ..., but that can't be done that
way when we use the --duration filter, as we have to wait for the syscall exit
to calculate the duration and decide if it should be filtered, so we have to
disable the interrupted logic and only print at syscall exit, duh.

Before:

  # trace --duration 100
  <SNIP>
   9.248 (0.023 ms): gnome-shell/2287 poll(ufds: 0x7ffc5ea26580, nfds: 1, timeout_msecs: 4294967295) ...
   9.296 (0.001 ms): gnome-shell/2287 recvmsg(fd: 11<socket:[35818]>, msg: 0x7ffc5ea264a0          ) ...
   9.311 (0.008 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                         ) ...
   9.859 (0.023 ms): gnome-shell/2287 poll(ufds: 0x7ffc5ea24250, nfds: 1, timeout_msecs: 4294967295) ...
   9.942 (0.051 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                         ) ...
  10.467 (0.003 ms): gnome-shell/2287 poll(ufds: 0x55e623431220, nfds: 50, timeout_msecs: 4294967295) ...
  11.136 (0.382 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                         ) ...
  11.223 (0.023 ms): SoftwareVsyncT/24369 futex(uaddr: 0x7f5ec5df8c14, op: WAIT_BITSET|PRIV, val: 1, utime: 0x7f5ec5df8b68, val3: 4294967295) ...
  16.865 (5.501 ms): firefox/24321 poll(ufds: 0x7f5ec388b460, nfds: 6, timeout_msecs: 4294967295   ) ...
  22.571 (0.006 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                         ) ...
  26.793 (4.063 ms): gnome-shell/2287 poll(ufds: 0x55e623431220, nfds: 50, timeout_msecs: 4294967295) ...
  26.917 (0.080 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                         ) ...
  27.291 (0.355 ms): qemu-system-x8/10065 ppoll(ufds: 0x55c98b39e400, nfds: 72, tsp: 0x7fffe4e4fe60, sigsetsize: 8) ...
  27.336 (0.012 ms): SoftwareVsyncT/24369 futex(uaddr: 0x7f5ec5df8c14, op: WAIT_BITSET|PRIV, val: 1, utime: 0x7f5ec5df8b68, val3: 4294967295) ...
  33.370 (5.958 ms): firefox/24321 poll(ufds: 0x7f5ec388b460, nfds: 6, timeout_msecs: 4294967295) ...
  33.866 (0.021 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                      ) ...
  35.762 (1.611 ms): gnome-shell/2287 poll(ufds: 0x55e623431220, nfds: 50, timeout_msecs: 8     ) ...
  38.765 (2.910 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                      ) ...

After:

  # trace --duration 100

  238.292 (153.226 ms): hexchat/2786 poll(ufds: 0x559ea372f370, nfds: 6, timeout_msecs: 153) = 0 Timeout
  249.634 (199.433 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x7ffdcbb63610        ) = 1
  385.583 (147.257 ms): hexchat/2786 poll(ufds: 0x559ea372f370, nfds: 6, timeout_msecs: 147) = 0 Timeout
  397.166 (110.779 ms): gnome-shell/2287 poll(ufds: 0x55e623431220, nfds: 50, timeout_msecs: 4294967295) = 1
  601.839 (132.066 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x8316a0                          ) = 1
  602.445 (132.679 ms): gnome-shell/2287 poll(ufds: 0x55e623431220, nfds: 50, timeout_msecs: 4294967295) = 1
  686.122 (300.418 ms): hexchat/2786 poll(ufds: 0x559ea372f370, nfds: 6, timeout_msecs: 300) = 0 Timeout
  815.033 (184.641 ms): JS Helper/24352 futex(uaddr: 0x7f5ed98e584c, op: WAIT|PRIV, val: 1149859) = 0
  825.868 (195.469 ms): JS Helper/24351 futex(uaddr: 0x7f5ed98e584c, op: WAIT|PRIV, val: 1149860) = 0
  840.738 (210.335 ms): JS Helper/24350 futex(uaddr: 0x7f5ed98e584c, op: WAIT|PRIV, val: 1149861) = 0
  914.898 (158.692 ms): Compositor/24363 futex(uaddr: 0x7f5ec8dfebf4, op: WAIT|PRIV, val: 1) = 0
  915.199 (100.747 ms): Timer/24358 futex(uaddr: 0x7f5ed98e56cc, op: WAIT_BITSET|PRIV|CLKRT, val: 2545397, utime: 0x7f5ecdbfec30, val3: 4294967295) = 0
  986.639 (247.325 ms): hexchat/2786 poll(ufds: 0x559ea372f370, nfds: 6, timeout_msecs: 247) = 0 Timeout
  996.239 (500.591 ms): chrome/16237 poll(ufds: 0x3ecd739bd0, nfds: 5, timeout_msecs: 500) = 0 Timeout
 1042.890 (120.076 ms): Timer/24358 futex(uaddr: 0x7f5ed98e56cc, op: WAIT_BITSET|PRIV|CLKRT, val: 2545403, utime: 0x7f5ecdbfec30, val3: 4294967295) = -1 ETIMEDOUT Connection timed out

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-d2nay6kjax5ro991c9kelvi5@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 39a158923acf..65f6abe75d71 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1849,7 +1849,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 			goto out_put;
 	}
 
-	if (!trace->summary_only)
+	if (!(trace->duration_filter || trace->summary_only))
 		trace__printf_interrupted_entry(trace, sample);
 
 	ttrace->entry_time = sample->time;
-- 
2.5.5

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

* [PATCH 11/15] perf trace: Introduce --min-stack filter
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (9 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 10/15] perf trace: Do not print interrupted syscalls when using --duration Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 12/15] perf record: Export record_opts based callchain parsing helper Arnaldo Carvalho de Melo
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Counterpart to --max-stack, to help focusing on deeply nested calls. Can
be combined with --duration, etc.

E.g.:

  System wide syscall tracing looking for call stacks longer than 66:

  # trace --mmap-pages 32768 --filter-pid 2711 --call-graph dwarf,16384 --min-stack 66

  Or more compactly:

  # trace -m 32768 --filt 2711 --call dwarf,16384 --min-st 66
   363.027 ( 0.002 ms): gnome-shell/2287 poll(ufds: 0x7ffc5ea24230, nfds: 1, timeout_msecs: 4294967295         ) = 1
                                       [0xf6fdd] (/usr/lib64/libc-2.22.so)
                                       _xcb_conn_wait+0x92 (/usr/lib64/libxcb.so.1.1.0)
                                       _xcb_out_send+0x4d (/usr/lib64/libxcb.so.1.1.0)
                                       xcb_writev+0x45 (/usr/lib64/libxcb.so.1.1.0)
                                       _XSend+0x19e (/usr/lib64/libX11.so.6.3.0)
                                       _XReply+0x82 (/usr/lib64/libX11.so.6.3.0)
                                       XSync+0x4d (/usr/lib64/libX11.so.6.3.0)
                                       dri3_bind_tex_image+0x42 (/usr/lib64/libGL.so.1.2.0)
                                       _cogl_winsys_texture_pixmap_x11_update+0x117 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_texture_pixmap_x11_update+0x67 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_texture_pixmap_x11_pre_paint+0x13 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_pipeline_layer_pre_paint+0x5e (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_rectangles_validate_layer_cb+0x1b (/usr/lib64/libcogl.so.20.4.1)
                                       cogl_pipeline_foreach_layer+0xbe (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_framebuffer_draw_multitextured_rectangles+0x77 (/usr/lib64/libcogl.so.20.4.1)
                                       cogl_framebuffer_draw_multitextured_rectangle+0x51 (/usr/lib64/libcogl.so.20.4.1)
                                       paint_clipped_rectangle+0xb6 (/usr/lib64/libmutter.so.0.0.0)
                                       meta_shaped_texture_paint+0x3e3 (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_window_actor_paint+0x14b (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_window_group_paint+0x19f (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       [0x3d970] (/usr/lib64/gnome-shell/libgnome-shell.so)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_stage_paint+0x3a (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_stage_paint+0x45 (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0x164 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _clutter_stage_do_paint+0x17b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_stage_cogl_redraw+0x496 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _clutter_stage_do_update+0x117 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_clock_dispatch+0x169 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       g_main_context_dispatch+0x15a (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       g_main_context_iterate.isra.29+0x1e0 (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       g_main_loop_run+0xc2 (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       meta_run+0x2c (/usr/lib64/libmutter.so.0.0.0)
                                       main+0x3f7 (/usr/bin/gnome-shell)
                                       __libc_start_main+0xf0 (/usr/lib64/libc-2.22.so)
                                       [0x2909] (/usr/bin/gnome-shell)
   363.038 ( 0.006 ms): gnome-shell/2287 writev(fd: 5<socket:[32540]>, vec: 0x7ffc5ea243a0, vlen: 3            ) = 4
                                       __GI___writev+0x2d (/usr/lib64/libc-2.22.so)
                                       _xcb_conn_wait+0x359 (/usr/lib64/libxcb.so.1.1.0)
                                       _xcb_out_send+0x4d (/usr/lib64/libxcb.so.1.1.0)
                                       xcb_writev+0x45 (/usr/lib64/libxcb.so.1.1.0)
                                       _XSend+0x19e (/usr/lib64/libX11.so.6.3.0)
                                       _XReply+0x82 (/usr/lib64/libX11.so.6.3.0)
                                       XSync+0x4d (/usr/lib64/libX11.so.6.3.0)
                                       dri3_bind_tex_image+0x42 (/usr/lib64/libGL.so.1.2.0)
                                       _cogl_winsys_texture_pixmap_x11_update+0x117 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_texture_pixmap_x11_update+0x67 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_texture_pixmap_x11_pre_paint+0x13 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_pipeline_layer_pre_paint+0x5e (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_rectangles_validate_layer_cb+0x1b (/usr/lib64/libcogl.so.20.4.1)
                                       cogl_pipeline_foreach_layer+0xbe (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_framebuffer_draw_multitextured_rectangles+0x77 (/usr/lib64/libcogl.so.20.4.1)
                                       cogl_framebuffer_draw_multitextured_rectangle+0x51 (/usr/lib64/libcogl.so.20.4.1)
                                       paint_clipped_rectangle+0xb6 (/usr/lib64/libmutter.so.0.0.0)
                                       meta_shaped_texture_paint+0x3e3 (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_window_actor_paint+0x14b (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_window_group_paint+0x19f (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       [0x3d970] (/usr/lib64/gnome-shell/libgnome-shell.so)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_stage_paint+0x3a (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_stage_paint+0x45 (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0x164 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _clutter_stage_do_paint+0x17b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_stage_cogl_redraw+0x496 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _clutter_stage_do_update+0x117 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_clock_dispatch+0x169 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       g_main_context_dispatch+0x15a (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       g_main_context_iterate.isra.29+0x1e0 (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       g_main_loop_run+0xc2 (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       meta_run+0x2c (/usr/lib64/libmutter.so.0.0.0)
                                       main+0x3f7 (/usr/bin/gnome-shell)
                                       __libc_start_main+0xf0 (/usr/lib64/libc-2.22.so)
                                       [0x2909] (/usr/bin/gnome-shell)
   363.086 ( 0.042 ms): gnome-shell/2287 poll(ufds: 0x7ffc5ea24250, nfds: 1, timeout_msecs: 4294967295         ) = 1
                                       [0xf6fdd] (/usr/lib64/libc-2.22.so)
                                       _xcb_conn_wait+0x92 (/usr/lib64/libxcb.so.1.1.0)
                                       wait_for_reply+0xb7 (/usr/lib64/libxcb.so.1.1.0)
                                       xcb_wait_for_reply+0x61 (/usr/lib64/libxcb.so.1.1.0)
                                       _XReply+0x127 (/usr/lib64/libX11.so.6.3.0)
                                       XSync+0x4d (/usr/lib64/libX11.so.6.3.0)
                                       dri3_bind_tex_image+0x42 (/usr/lib64/libGL.so.1.2.0)
                                       _cogl_winsys_texture_pixmap_x11_update+0x117 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_texture_pixmap_x11_update+0x67 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_texture_pixmap_x11_pre_paint+0x13 (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_pipeline_layer_pre_paint+0x5e (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_rectangles_validate_layer_cb+0x1b (/usr/lib64/libcogl.so.20.4.1)
                                       cogl_pipeline_foreach_layer+0xbe (/usr/lib64/libcogl.so.20.4.1)
                                       _cogl_framebuffer_draw_multitextured_rectangles+0x77 (/usr/lib64/libcogl.so.20.4.1)
                                       cogl_framebuffer_draw_multitextured_rectangle+0x51 (/usr/lib64/libcogl.so.20.4.1)
                                       paint_clipped_rectangle+0xb6 (/usr/lib64/libmutter.so.0.0.0)
                                       meta_shaped_texture_paint+0x3e3 (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_window_actor_paint+0x14b (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_real_paint+0x20 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_window_group_paint+0x19f (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       [0x3d970] (/usr/lib64/gnome-shell/libgnome-shell.so)
                                       _g_closure_invoke_va+0xb2 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_stage_paint+0x3a (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       meta_stage_paint+0x45 (/usr/lib64/libmutter.so.0.0.0)
                                       _g_closure_invoke_va+0x164 (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit_valist+0xc0d (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       g_signal_emit+0x8f (/usr/lib64/libgobject-2.0.so.0.4600.2)
                                       clutter_actor_continue_paint+0x2bb (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_actor_paint.part.41+0x47b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _clutter_stage_do_paint+0x17b (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_stage_cogl_redraw+0x496 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       _clutter_stage_do_update+0x117 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       clutter_clock_dispatch+0x169 (/usr/lib64/libclutter-1.0.so.0.2400.2)
                                       g_main_context_dispatch+0x15a (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       g_main_context_iterate.isra.29+0x1e0 (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       g_main_loop_run+0xc2 (/usr/lib64/libglib-2.0.so.0.4600.2)
                                       meta_run+0x2c (/usr/lib64/libmutter.so.0.0.0)
                                       main+0x3f7 (/usr/bin/gnome-shell)
                                       __libc_start_main+0xf0 (/usr/lib64/libc-2.22.so)
                                       [0x2909] (/usr/bin/gnome-shell)

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-jncuxju9fibq2rl6olhqwjw6@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt |  4 +++
 tools/perf/builtin-trace.c              | 55 ++++++++++++++++++++++-----------
 2 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 2ee0c4fee18d..4e8baa75a32e 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -138,6 +138,10 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
 
         Default: 127
 
+--min-stack::
+        Set the stack depth limit when parsing the callchain, anything
+        below the specified depth will be ignored. Disabled by default.
+
 --proc-map-timeout::
 	When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
 	because the file may be huge. A time out is needed in such cases.
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 65f6abe75d71..6a64cb1344c7 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -108,6 +108,7 @@ struct trace {
 				proc_getname;
 	} stats;
 	unsigned int		max_stack;
+	unsigned int		min_stack;
 	bool			not_ev_qualifier;
 	bool			live;
 	bool			full_time;
@@ -1849,7 +1850,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 			goto out_put;
 	}
 
-	if (!(trace->duration_filter || trace->summary_only))
+	if (!(trace->duration_filter || trace->summary_only || trace->min_stack))
 		trace__printf_interrupted_entry(trace, sample);
 
 	ttrace->entry_time = sample->time;
@@ -1860,7 +1861,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
 					   args, trace, thread);
 
 	if (sc->is_exit) {
-		if (!trace->duration_filter && !trace->summary_only) {
+		if (!(trace->duration_filter || trace->summary_only || trace->min_stack)) {
 			trace__fprintf_entry_head(trace, thread, 1, sample->time, trace->output);
 			fprintf(trace->output, "%-70s\n", ttrace->entry_str);
 		}
@@ -1880,26 +1881,26 @@ out_put:
 	return err;
 }
 
-static int trace__fprintf_callchain(struct trace *trace, struct perf_evsel *evsel,
-				    struct perf_sample *sample)
+static int trace__resolve_callchain(struct trace *trace, struct perf_evsel *evsel,
+				    struct perf_sample *sample,
+				    struct callchain_cursor *cursor)
 {
 	struct addr_location al;
+
+	if (machine__resolve(trace->host, &al, sample) < 0 ||
+	    thread__resolve_callchain(al.thread, cursor, evsel, sample, NULL, NULL, trace->max_stack))
+		return -1;
+
+	return 0;
+}
+
+static int trace__fprintf_callchain(struct trace *trace, struct perf_sample *sample)
+{
 	/* TODO: user-configurable print_opts */
 	const unsigned int print_opts = EVSEL__PRINT_SYM |
 				        EVSEL__PRINT_DSO |
 				        EVSEL__PRINT_UNKNOWN_AS_ADDR;
 
-	if (sample->callchain == NULL)
-		return 0;
-
-	if (machine__resolve(trace->host, &al, sample) < 0 ||
-	    thread__resolve_callchain(al.thread, &callchain_cursor, evsel,
-				      sample, NULL, NULL, trace->max_stack)) {
-		pr_err("Problem processing %s callchain, skipping...\n",
-			perf_evsel__name(evsel));
-		return 0;
-	}
-
 	return sample__fprintf_callchain(sample, 38, print_opts, &callchain_cursor, trace->output);
 }
 
@@ -1910,7 +1911,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 	long ret;
 	u64 duration = 0;
 	struct thread *thread;
-	int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1;
+	int id = perf_evsel__sc_tp_uint(evsel, id, sample), err = -1, callchain_ret = 0;
 	struct syscall *sc = trace__syscall_info(trace, evsel, id);
 	struct thread_trace *ttrace;
 
@@ -1942,6 +1943,15 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
 	} else if (trace->duration_filter)
 		goto out;
 
+	if (sample->callchain) {
+		callchain_ret = trace__resolve_callchain(trace, evsel, sample, &callchain_cursor);
+		if (callchain_ret == 0) {
+			if (callchain_cursor.nr < trace->min_stack)
+				goto out;
+			callchain_ret = 1;
+		}
+	}
+
 	if (trace->summary_only)
 		goto out;
 
@@ -1982,7 +1992,10 @@ signed_print:
 
 	fputc('\n', trace->output);
 
-	trace__fprintf_callchain(trace, evsel, sample);
+	if (callchain_ret > 0)
+		trace__fprintf_callchain(trace, sample);
+	else if (callchain_ret < 0)
+		pr_err("Problem processing %s callchain, skipping...\n", perf_evsel__name(evsel));
 out:
 	ttrace->entry_pending = false;
 	err = 0;
@@ -2131,7 +2144,10 @@ static int trace__event_handler(struct trace *trace, struct perf_evsel *evsel,
 
 	fprintf(trace->output, ")\n");
 
-	trace__fprintf_callchain(trace, evsel, sample);
+	if (sample->callchain) {
+		if (trace__resolve_callchain(trace, evsel, sample, &callchain_cursor) == 0)
+			trace__fprintf_callchain(trace, sample);
+	}
 
 	return 0;
 }
@@ -3082,6 +3098,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		     &record_parse_callchain_opt),
 	OPT_BOOLEAN(0, "kernel-syscall-graph", &trace.kernel_syscallchains,
 		    "Show the kernel callchains on the syscall exit path"),
+	OPT_UINTEGER(0, "min-stack", &trace.min_stack,
+		     "Set the minimum stack depth when parsing the callchain, "
+		     "anything below the specified depth will be ignored."),
 	OPT_UINTEGER(0, "max-stack", &trace.max_stack,
 		     "Set the maximum stack depth when parsing the callchain, "
 		     "anything beyond the specified depth will be ignored. "
-- 
2.5.5

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

* [PATCH 12/15] perf record: Export record_opts based callchain parsing helper
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (10 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 11/15] perf trace: Introduce --min-stack filter Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:50 ` [PATCH 13/15] perf trace: Make --(min,max}-stack imply "--call-graph dwarf" Arnaldo Carvalho de Melo
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

To be able to call it outside option parsing, like when setting a
default --call-graph parameter in 'perf trace' when just --min-stack is
used.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-xay69plylwibpb3l4isrpl1k@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c | 35 ++++++++++++++++++++---------------
 tools/perf/util/callchain.h |  6 ++++++
 2 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 3239a6ec9d23..5b4758a08a49 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -930,45 +930,50 @@ out_delete_session:
 	return status;
 }
 
-static void callchain_debug(void)
+static void callchain_debug(struct callchain_param *callchain)
 {
 	static const char *str[CALLCHAIN_MAX] = { "NONE", "FP", "DWARF", "LBR" };
 
-	pr_debug("callchain: type %s\n", str[callchain_param.record_mode]);
+	pr_debug("callchain: type %s\n", str[callchain->record_mode]);
 
-	if (callchain_param.record_mode == CALLCHAIN_DWARF)
+	if (callchain->record_mode == CALLCHAIN_DWARF)
 		pr_debug("callchain: stack dump size %d\n",
-			 callchain_param.dump_size);
+			 callchain->dump_size);
 }
 
-int record_parse_callchain_opt(const struct option *opt,
-			       const char *arg,
-			       int unset)
+int record_opts__parse_callchain(struct record_opts *record,
+				 struct callchain_param *callchain,
+				 const char *arg, bool unset)
 {
 	int ret;
-	struct record_opts *record = (struct record_opts *)opt->value;
-
 	record->callgraph_set = true;
-	callchain_param.enabled = !unset;
+	callchain->enabled = !unset;
 
 	/* --no-call-graph */
 	if (unset) {
-		callchain_param.record_mode = CALLCHAIN_NONE;
+		callchain->record_mode = CALLCHAIN_NONE;
 		pr_debug("callchain: disabled\n");
 		return 0;
 	}
 
-	ret = parse_callchain_record_opt(arg, &callchain_param);
+	ret = parse_callchain_record_opt(arg, callchain);
 	if (!ret) {
 		/* Enable data address sampling for DWARF unwind. */
-		if (callchain_param.record_mode == CALLCHAIN_DWARF)
+		if (callchain->record_mode == CALLCHAIN_DWARF)
 			record->sample_address = true;
-		callchain_debug();
+		callchain_debug(callchain);
 	}
 
 	return ret;
 }
 
+int record_parse_callchain_opt(const struct option *opt,
+			       const char *arg,
+			       int unset)
+{
+	return record_opts__parse_callchain(opt->value, &callchain_param, arg, unset);
+}
+
 int record_callchain_opt(const struct option *opt,
 			 const char *arg __maybe_unused,
 			 int unset __maybe_unused)
@@ -981,7 +986,7 @@ int record_callchain_opt(const struct option *opt,
 	if (callchain_param.record_mode == CALLCHAIN_NONE)
 		callchain_param.record_mode = CALLCHAIN_FP;
 
-	callchain_debug();
+	callchain_debug(&callchain_param);
 	return 0;
 }
 
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index cae5a7b1f5c8..65e2a4f7cb4e 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -212,6 +212,12 @@ struct hist_entry;
 int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset);
 int record_callchain_opt(const struct option *opt, const char *arg, int unset);
 
+struct record_opts;
+
+int record_opts__parse_callchain(struct record_opts *record,
+				 struct callchain_param *callchain,
+				 const char *arg, bool unset);
+
 int sample__resolve_callchain(struct perf_sample *sample,
 			      struct callchain_cursor *cursor, struct symbol **parent,
 			      struct perf_evsel *evsel, struct addr_location *al,
-- 
2.5.5

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

* [PATCH 13/15] perf trace: Make --(min,max}-stack imply "--call-graph dwarf"
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (11 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 12/15] perf record: Export record_opts based callchain parsing helper Arnaldo Carvalho de Melo
@ 2016-04-15 21:50 ` Arnaldo Carvalho de Melo
  2016-04-15 21:51 ` [PATCH 14/15] perf evlist: Expose perf_event_mlock_kb_in_pages() helper Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:50 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

If one uses:

  # perf trace --min-stack 16

Then it implicitly means that callgraphs should be enabled, and the best
option in terms of widespread availability is "dwarf".

Further work needed to choose a better alternative, LBR, in capable
systems.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-xtjmnpkyk42npekxz3kynzmx@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt |  6 ++++++
 tools/perf/builtin-trace.c              | 13 ++++++++++++-
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 4e8baa75a32e..146c6db21cbf 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -136,12 +136,18 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
         not limiting, the overhead of callchains needs to be set via the
         knobs in --call-graph dwarf.
 
+        Implies '--call-graph dwarf' when --call-graph not present on the
+        command line, on systems where DWARF unwinding was built in.
+
         Default: 127
 
 --min-stack::
         Set the stack depth limit when parsing the callchain, anything
         below the specified depth will be ignored. Disabled by default.
 
+        Implies '--call-graph dwarf' when --call-graph not present on the
+        command line, on systems where DWARF unwinding was built in.
+
 --proc-map-timeout::
 	When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
 	because the file may be huge. A time out is needed in such cases.
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 6a64cb1344c7..19f5100acc1d 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3047,7 +3047,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		.show_comm = true,
 		.trace_syscalls = true,
 		.kernel_syscallchains = false,
-		.max_stack = PERF_MAX_STACK_DEPTH,
+		.max_stack = UINT_MAX,
 	};
 	const char *output_name = NULL;
 	const char *ev_qualifier_str = NULL;
@@ -3109,6 +3109,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 			"per thread proc mmap processing timeout in ms"),
 	OPT_END()
 	};
+	bool max_stack_user_set = true;
 	const char * const trace_subcommands[] = { "record", NULL };
 	int err;
 	char bf[BUFSIZ];
@@ -3142,6 +3143,16 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		trace.opts.sample_time = true;
 	}
 
+	if (trace.max_stack == UINT_MAX) {
+		trace.max_stack = PERF_MAX_STACK_DEPTH;
+		max_stack_user_set = false;
+	}
+
+#ifdef HAVE_DWARF_UNWIND_SUPPORT
+	if ((trace.min_stack || max_stack_user_set) && !trace.opts.callgraph_set)
+		record_opts__parse_callchain(&trace.opts, &callchain_param, "dwarf", false);
+#endif
+
 	if (trace.opts.callgraph_set)
 		symbol_conf.use_callchain = true;
 
-- 
2.5.5

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

* [PATCH 14/15] perf evlist: Expose perf_event_mlock_kb_in_pages() helper
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (12 preceding siblings ...)
  2016-04-15 21:50 ` [PATCH 13/15] perf trace: Make --(min,max}-stack imply "--call-graph dwarf" Arnaldo Carvalho de Melo
@ 2016-04-15 21:51 ` Arnaldo Carvalho de Melo
  2016-04-15 21:51 ` [PATCH 15/15] perf trace: Bump --mmap-pages when --call-graph is used by the root user Arnaldo Carvalho de Melo
  2016-04-16  9:12 ` [GIT PULL 00/15] perf/core improvements Ingo Molnar
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:51 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

When the user doesn't set --mmap-pages, perf_evlist__mmap() will do it
by reading the maximum possible for a non-root user from the
/proc/sys/kernel/perf_event_mlock_kb file.

Expose that function so that 'perf trace' can, for root users, to bump
mmap-pages to a higher value for root, based on the contents of this
proc file.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-xay69plylwibpb3l4isrpl1k@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evlist.c | 42 +++++++++++++++++++++++++-----------------
 tools/perf/util/evlist.h |  2 ++
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 4c9f510ae18d..6fb5725821de 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -986,26 +986,34 @@ out_unmap:
 	return -1;
 }
 
-static size_t perf_evlist__mmap_size(unsigned long pages)
+unsigned long perf_event_mlock_kb_in_pages(void)
 {
-	if (pages == UINT_MAX) {
-		int max;
+	unsigned long pages;
+	int max;
 
-		if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
-			/*
-			 * Pick a once upon a time good value, i.e. things look
-			 * strange since we can't read a sysctl value, but lets not
-			 * die yet...
-			 */
-			max = 512;
-		} else {
-			max -= (page_size / 1024);
-		}
+	if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
+		/*
+		 * Pick a once upon a time good value, i.e. things look
+		 * strange since we can't read a sysctl value, but lets not
+		 * die yet...
+		 */
+		max = 512;
+	} else {
+		max -= (page_size / 1024);
+	}
+
+	pages = (max * 1024) / page_size;
+	if (!is_power_of_2(pages))
+		pages = rounddown_pow_of_two(pages);
 
-		pages = (max * 1024) / page_size;
-		if (!is_power_of_2(pages))
-			pages = rounddown_pow_of_two(pages);
-	} else if (!is_power_of_2(pages))
+	return pages;
+}
+
+static size_t perf_evlist__mmap_size(unsigned long pages)
+{
+	if (pages == UINT_MAX)
+		pages = perf_event_mlock_kb_in_pages();
+	else if (!is_power_of_2(pages))
 		return 0;
 
 	return (pages + 1) * page_size;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index da46423998e8..208897a646ca 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -158,6 +158,8 @@ int perf_evlist__parse_mmap_pages(const struct option *opt,
 				  const char *str,
 				  int unset);
 
+unsigned long perf_event_mlock_kb_in_pages(void);
+
 int perf_evlist__mmap_ex(struct perf_evlist *evlist, unsigned int pages,
 			 bool overwrite, unsigned int auxtrace_pages,
 			 bool auxtrace_overwrite);
-- 
2.5.5

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

* [PATCH 15/15] perf trace: Bump --mmap-pages when --call-graph is used by the root user
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (13 preceding siblings ...)
  2016-04-15 21:51 ` [PATCH 14/15] perf evlist: Expose perf_event_mlock_kb_in_pages() helper Arnaldo Carvalho de Melo
@ 2016-04-15 21:51 ` Arnaldo Carvalho de Melo
  2016-04-16  9:12 ` [GIT PULL 00/15] perf/core improvements Ingo Molnar
  15 siblings, 0 replies; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-15 21:51 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan

From: Arnaldo Carvalho de Melo <acme@redhat.com>

To reduce the chances we'll overflow the mmap buffer, manual fine tuning
trumps this.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Milian Wolff <milian.wolff@kdab.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-wxygbxmp1v9mng1ea28wet02@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt |  4 ++++
 tools/perf/builtin-trace.c              | 10 +++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 146c6db21cbf..c075c002eaa4 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -123,6 +123,10 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
         man pages for details. The ones that are most useful in 'perf trace'
         are 'dwarf' and 'lbr', where available, try: 'perf trace --call-graph dwarf'.
 
+        Using this will, for the root user, bump the value of --mmap-pages to 4
+        times the maximum for non-root users, based on the kernel.perf_event_mlock_kb
+        sysctl. This is done only if the user doesn't specify a --mmap-pages value.
+
 --kernel-syscall-graph::
 	 Show the kernel callchains on the syscall exit path.
 
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 19f5100acc1d..026ec0c749b0 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3110,6 +3110,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_END()
 	};
 	bool max_stack_user_set = true;
+	bool mmap_pages_user_set = true;
 	const char * const trace_subcommands[] = { "record", NULL };
 	int err;
 	char bf[BUFSIZ];
@@ -3143,6 +3144,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		trace.opts.sample_time = true;
 	}
 
+	if (trace.opts.mmap_pages == UINT_MAX)
+		mmap_pages_user_set = false;
+
 	if (trace.max_stack == UINT_MAX) {
 		trace.max_stack = PERF_MAX_STACK_DEPTH;
 		max_stack_user_set = false;
@@ -3153,8 +3157,12 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		record_opts__parse_callchain(&trace.opts, &callchain_param, "dwarf", false);
 #endif
 
-	if (trace.opts.callgraph_set)
+	if (trace.opts.callgraph_set) {
+		if (!mmap_pages_user_set && geteuid() == 0)
+			trace.opts.mmap_pages = perf_event_mlock_kb_in_pages() * 4;
+
 		symbol_conf.use_callchain = true;
+	}
 
 	if (trace.evlist->nr_entries > 0)
 		evlist__set_evsel_handler(trace.evlist, trace__event_handler);
-- 
2.5.5

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

* Re: [GIT PULL 00/15] perf/core improvements
  2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
                   ` (14 preceding siblings ...)
  2016-04-15 21:51 ` [PATCH 15/15] perf trace: Bump --mmap-pages when --call-graph is used by the root user Arnaldo Carvalho de Melo
@ 2016-04-16  9:12 ` Ingo Molnar
  15 siblings, 0 replies; 19+ messages in thread
From: Ingo Molnar @ 2016-04-16  9:12 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Adrian Hunter, David Ahern, Frederic Weisbecker,
	Jiri Olsa, Milian Wolff, Namhyung Kim, Wang Nan,
	Arnaldo Carvalho de Melo


* Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> Hi Ingo,
> 
> 	Please consider pulling,
> 
> - Arnaldo
> 
> The following changes since commit 0b22cd276cec21107d9d69453fa58abba73e71df:
> 
>   Merge tag 'perf-core-for-mingo-20160414' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2016-04-14 15:30:59 +0200)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160415
> 
> for you to fetch changes up to f3e459d16a8493b617ccf2a940330279679e0291:
> 
>   perf trace: Bump --mmap-pages when --call-graph is used by the root user (2016-04-15 17:52:34 -0300)
> 
> ----------------------------------------------------------------
> perf/core improvements:
> 
> User visible:
> 
> - Wire the callchain unwinding "max-stack" know to 'perf script --max-stack',
>   allowing to limit the depth of callchains, possibly reducing processing
>   time (Arnaldo Carvalho de Melo)
> 
> - Ditto for 'perf trace --max-stack' (Arnaldo Carvalho de Melo)
> 
> - Introduce a --min-stack filter for 'perf trace', to show syscalls that
>   had a userspace callchain leading to it at least min-stack deep (Arnaldo Carvalho de Melo)
> 
> - Make 'perf trace' work with multiple threads and the --duration filter,
>   i.e. do not print the start of an interrupted syscall followed by ...
>   to print interrupts from other threads, as we need to wait the sys_exit
>   syscall tracepoint to calculate the duration, duh. (Arnaldo Carvalho de Melo)
> 
>   System wide --duration now works as expected:
> 
>    [root@jouet ~]# trace --duration 100
>      152.393 (145.147 ms): Timer/24358 futex(uaddr: 0x7f5ed98e56cc, op: WAIT_BITSET|PRIV|CLKRT, val: 7055125, utime: 0x7f5ecdbfec30, val3: 4294967295) = -1 ETIMEDOUT Connection timed out
>      152.438 (145.040 ms): firefox/24321 poll(ufds: 0x7f5ec388b460, nfds: 6, timeout_msecs: 4294967295) = 1
>      358.580 (158.279 ms): Xorg/2025 select(n: 512, inp: 0x83a8e0, tvp: 0x7ffdcbb63610) = 0 Timeout
>      358.687 (148.285 ms): gnome-terminal/2711 poll(ufds: 0x55b7e6811ad0, nfds: 15, timeout_msecs: 249) = 1
>      370.150 (169.569 ms): gnome-shell/2287 poll(ufds: 0x55e623d65490, nfds: 86, timeout_msecs: 4294967295) = 1
> 
> - Now 'perf trace's --max-stack and --min-stack will automatically set
>   "--call-graph dwarf", if --call-graph is not present on the command line:
> 
>    [root@jouet ~]# perf trace -e nanosleep --max-stack 3 usleep 1
>      0.299 ( 0.057 ms): usleep/29658 nanosleep(rqtp: 0x7fff80f3b230) = 0
>                                        __nanosleep+0x10 (/usr/lib64/libc-2.22.so)
>                                        usleep+0x34 (/usr/lib64/libc-2.22.so)
>                                        main+0x1eb (/usr/bin/usleep)
>    [root@jouet ~]#
> 
> - Bump 'perf trace --mmap-pages' for root when using callchains and not
>   specifying --mmap-pages explicitely (Arnaldo Carvalho de Melo)
> 
> Build fixes:
> 
> - The python binding object had missing symbols, to some refactoring
>   to fix that (Arnaldo Carvalho de Melo)
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> ----------------------------------------------------------------
> Arnaldo Carvalho de Melo (15):
>       perf trace: Move socket_type beautifier to tools/perf/trace/beauty/
>       perf callchain: Start moving away from global per thread cursors
>       perf evsel: Remove symbol_conf usage
>       perf symbols: Move fprintf routines to separate object file
>       perf evsel: Require that callchains be resolved before calling fprintf_{sym,callchain}
>       perf tools: Remove addr_location argument to sample__fprintf_callchain
>       perf script: Add --max-stack knob
>       perf trace: Add --max-stack knob
>       perf evsel: Move fprintf methods to separate source file
>       perf trace: Do not print interrupted syscalls when using --duration
>       perf trace: Introduce --min-stack filter
>       perf record: Export record_opts based callchain parsing helper
>       perf trace: Make --(min,max}-stack imply "--call-graph dwarf"
>       perf evlist: Expose perf_event_mlock_kb_in_pages() helper
>       perf trace: Bump --mmap-pages when --call-graph is used by the root user
> 
>  tools/perf/Documentation/perf-script.txt           |  10 +
>  tools/perf/Documentation/perf-trace.txt            |  23 +++
>  tools/perf/builtin-kmem.c                          |   2 +-
>  tools/perf/builtin-record.c                        |  35 ++--
>  tools/perf/builtin-script.c                        |  39 ++--
>  tools/perf/builtin-trace.c                         | 144 +++++++-------
>  tools/perf/trace/beauty/socket_type.c              |  60 ++++++
>  tools/perf/util/Build                              |   2 +
>  tools/perf/util/callchain.c                        |   5 +-
>  tools/perf/util/callchain.h                        |   9 +-
>  tools/perf/util/evlist.c                           |  42 ++--
>  tools/perf/util/evlist.h                           |   2 +
>  tools/perf/util/evsel.c                            | 220 ---------------------
>  tools/perf/util/evsel.h                            |  19 +-
>  tools/perf/util/evsel_fprintf.c                    | 212 ++++++++++++++++++++
>  tools/perf/util/hist.c                             |   2 +-
>  tools/perf/util/machine.c                          |  26 +--
>  tools/perf/util/machine.h                          |   4 +
>  tools/perf/util/python-ext-sources                 |   1 +
>  .../perf/util/scripting-engines/trace-event-perl.c |   2 +-
>  .../util/scripting-engines/trace-event-python.c    |   2 +-
>  tools/perf/util/symbol.c                           |  71 -------
>  tools/perf/util/symbol.h                           |   5 +
>  tools/perf/util/symbol_fprintf.c                   |  71 +++++++
>  24 files changed, 565 insertions(+), 443 deletions(-)
>  create mode 100644 tools/perf/trace/beauty/socket_type.c
>  create mode 100644 tools/perf/util/evsel_fprintf.c
>  create mode 100644 tools/perf/util/symbol_fprintf.c

Pulled, thanks a lot Arnaldo!

	Ingo

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

* Re: [GIT PULL 00/15] perf/core improvements
  2011-10-06 17:22 Arnaldo Carvalho de Melo
@ 2011-10-10  5:11 ` Ingo Molnar
  0 siblings, 0 replies; 19+ messages in thread
From: Ingo Molnar @ 2011-10-10  5:11 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Andi Kleen, David Ahern, Frederic Weisbecker,
	Mike Galbraith, Paul Mackerras, Peter Zijlstra, Robert Richter,
	Stephane Eranian, Thomas Gleixner, arnaldo.melo


* Arnaldo Carvalho de Melo <acme@infradead.org> wrote:

> Hi Ingo,
> 
>         Please consider pulling from:
> 
> git://github.com/acmel/linux.git perf/core
> 
> 	It makes 'perf top' use the abstractions in 'perf report', allowing it
> to:
> 
> 1. Have total consistency with 'report'
> 
> 2. Allow --sort to be used to have more views than just 'dso, symbol'
>    Try 'perf top --sort comm' or 'pid' for instance
> 
> 3. All the goodies in the TUI, like zooming in/out threads, dsos, etc
> 
> 4. Integration with Live Annotation
> 
> 5. In the live annotation window, navigate to functions called by the one
>    being annotated (x86_64 only right now). This is just an experimentation
>    in increasing the integration of the multiple perf tools, more of this
>    kind to come.
> 
> 6. Initial callchain support, not yet decaying it over time as the main
>    view.
> 
> 	Also in this batch is the work Stephane did on including information
> about the machine where the perf.data file was collected.
> 
> Regards,
> 
> - Arnaldo
> 
> Arnaldo Carvalho de Melo (13):
>   perf hists: Stop using 'self' for struct hists
>   perf hists: Allow limiting the number of rows and columns in fprintf
>   perf report: Add option to show total period
>   perf hists: Threaded addition and sorting of entries
>   perf browsers: Add live mode to the hists, annotate browsers
>   perf top: Reuse the 'report' hist_entry/hists classes
>   perf top: Add callgraph support
>   perf annotate browser: Allow navigation to called functions
>   perf top: Use the TUI interface by default
>   perf annotate browser: Use -> to navigate on assembly lines
>   perf hists browser: Don't offer symbol actions when symbols not on --sort
>   perf hists browser: Fix TAB/UNTAB use with multiple events
>   perf hists browser: Update the browser.nr_entries after the timer
> 
> Stephane Eranian (2):
>   perf tools: Fix broken number of samples for perf report -n
>   perf tools: Make perf.data more self-descriptive (v8)
> 
>  tools/perf/Documentation/perf-report.txt |    8 +
>  tools/perf/Documentation/perf-script.txt |    7 +
>  tools/perf/Documentation/perf-top.txt    |   38 +-
>  tools/perf/Makefile                      |    4 -
>  tools/perf/arch/powerpc/Makefile         |    1 +
>  tools/perf/arch/powerpc/util/header.c    |   36 +
>  tools/perf/arch/x86/Makefile             |    1 +
>  tools/perf/arch/x86/util/header.c        |   59 ++
>  tools/perf/builtin-annotate.c            |    9 +-
>  tools/perf/builtin-diff.c                |    2 +-
>  tools/perf/builtin-record.c              |   15 +
>  tools/perf/builtin-report.c              |   17 +-
>  tools/perf/builtin-script.c              |    6 +-
>  tools/perf/builtin-top.c                 |  430 +++++++-----
>  tools/perf/builtin.h                     |    1 -
>  tools/perf/perf.h                        |   11 +
>  tools/perf/util/annotate.h               |    7 +-
>  tools/perf/util/evlist.c                 |    6 +
>  tools/perf/util/evlist.h                 |    4 +
>  tools/perf/util/evsel.c                  |    1 +
>  tools/perf/util/header.c                 | 1145 +++++++++++++++++++++++++++++-
>  tools/perf/util/header.h                 |   29 +-
>  tools/perf/util/hist.c                   |  338 +++++++---
>  tools/perf/util/hist.h                   |   33 +-
>  tools/perf/util/session.c                |   19 +
>  tools/perf/util/session.h                |    1 +
>  tools/perf/util/sort.h                   |    1 +
>  tools/perf/util/symbol.h                 |    1 +
>  tools/perf/util/top.c                    |  141 +----
>  tools/perf/util/top.h                    |   36 +-
>  tools/perf/util/ui/browsers/annotate.c   |   99 +++-
>  tools/perf/util/ui/browsers/hists.c      |  146 +++--
>  tools/perf/util/ui/browsers/top.c        |  236 ------
>  33 files changed, 2091 insertions(+), 797 deletions(-)
>  create mode 100644 tools/perf/arch/powerpc/util/header.c
>  create mode 100644 tools/perf/arch/x86/util/header.c
>  delete mode 100644 tools/perf/util/ui/browsers/top.c

Pulled, thanks a lot Arnaldo!

	Ingo

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

* [GIT PULL 00/15] perf/core improvements
@ 2011-10-06 17:22 Arnaldo Carvalho de Melo
  2011-10-10  5:11 ` Ingo Molnar
  0 siblings, 1 reply; 19+ messages in thread
From: Arnaldo Carvalho de Melo @ 2011-10-06 17:22 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Andi Kleen, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Mike Galbraith, Paul Mackerras,
	Peter Zijlstra, Robert Richter, Stephane Eranian,
	Thomas Gleixner, arnaldo.melo

Hi Ingo,

        Please consider pulling from:

git://github.com/acmel/linux.git perf/core

	It makes 'perf top' use the abstractions in 'perf report', allowing it
to:

1. Have total consistency with 'report'

2. Allow --sort to be used to have more views than just 'dso, symbol'
   Try 'perf top --sort comm' or 'pid' for instance

3. All the goodies in the TUI, like zooming in/out threads, dsos, etc

4. Integration with Live Annotation

5. In the live annotation window, navigate to functions called by the one
   being annotated (x86_64 only right now). This is just an experimentation
   in increasing the integration of the multiple perf tools, more of this
   kind to come.

6. Initial callchain support, not yet decaying it over time as the main
   view.

	Also in this batch is the work Stephane did on including information
about the machine where the perf.data file was collected.

Regards,

- Arnaldo

Arnaldo Carvalho de Melo (13):
  perf hists: Stop using 'self' for struct hists
  perf hists: Allow limiting the number of rows and columns in fprintf
  perf report: Add option to show total period
  perf hists: Threaded addition and sorting of entries
  perf browsers: Add live mode to the hists, annotate browsers
  perf top: Reuse the 'report' hist_entry/hists classes
  perf top: Add callgraph support
  perf annotate browser: Allow navigation to called functions
  perf top: Use the TUI interface by default
  perf annotate browser: Use -> to navigate on assembly lines
  perf hists browser: Don't offer symbol actions when symbols not on --sort
  perf hists browser: Fix TAB/UNTAB use with multiple events
  perf hists browser: Update the browser.nr_entries after the timer

Stephane Eranian (2):
  perf tools: Fix broken number of samples for perf report -n
  perf tools: Make perf.data more self-descriptive (v8)

 tools/perf/Documentation/perf-report.txt |    8 +
 tools/perf/Documentation/perf-script.txt |    7 +
 tools/perf/Documentation/perf-top.txt    |   38 +-
 tools/perf/Makefile                      |    4 -
 tools/perf/arch/powerpc/Makefile         |    1 +
 tools/perf/arch/powerpc/util/header.c    |   36 +
 tools/perf/arch/x86/Makefile             |    1 +
 tools/perf/arch/x86/util/header.c        |   59 ++
 tools/perf/builtin-annotate.c            |    9 +-
 tools/perf/builtin-diff.c                |    2 +-
 tools/perf/builtin-record.c              |   15 +
 tools/perf/builtin-report.c              |   17 +-
 tools/perf/builtin-script.c              |    6 +-
 tools/perf/builtin-top.c                 |  430 +++++++-----
 tools/perf/builtin.h                     |    1 -
 tools/perf/perf.h                        |   11 +
 tools/perf/util/annotate.h               |    7 +-
 tools/perf/util/evlist.c                 |    6 +
 tools/perf/util/evlist.h                 |    4 +
 tools/perf/util/evsel.c                  |    1 +
 tools/perf/util/header.c                 | 1145 +++++++++++++++++++++++++++++-
 tools/perf/util/header.h                 |   29 +-
 tools/perf/util/hist.c                   |  338 +++++++---
 tools/perf/util/hist.h                   |   33 +-
 tools/perf/util/session.c                |   19 +
 tools/perf/util/session.h                |    1 +
 tools/perf/util/sort.h                   |    1 +
 tools/perf/util/symbol.h                 |    1 +
 tools/perf/util/top.c                    |  141 +----
 tools/perf/util/top.h                    |   36 +-
 tools/perf/util/ui/browsers/annotate.c   |   99 +++-
 tools/perf/util/ui/browsers/hists.c      |  146 +++--
 tools/perf/util/ui/browsers/top.c        |  236 ------
 33 files changed, 2091 insertions(+), 797 deletions(-)
 create mode 100644 tools/perf/arch/powerpc/util/header.c
 create mode 100644 tools/perf/arch/x86/util/header.c
 delete mode 100644 tools/perf/util/ui/browsers/top.c


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

end of thread, other threads:[~2016-04-16  9:12 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-15 21:50 [GIT PULL 00/15] perf/core improvements Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 01/15] perf trace: Move socket_type beautifier to tools/perf/trace/beauty/ Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 02/15] perf callchain: Start moving away from global per thread cursors Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 03/15] perf evsel: Remove symbol_conf usage Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 04/15] perf symbols: Move fprintf routines to separate object file Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 05/15] perf evsel: Require that callchains be resolved before calling fprintf_{sym,callchain} Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 06/15] perf tools: Remove addr_location argument to sample__fprintf_callchain Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 07/15] perf script: Add --max-stack knob Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 08/15] perf trace: " Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 09/15] perf evsel: Move fprintf methods to separate source file Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 10/15] perf trace: Do not print interrupted syscalls when using --duration Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 11/15] perf trace: Introduce --min-stack filter Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 12/15] perf record: Export record_opts based callchain parsing helper Arnaldo Carvalho de Melo
2016-04-15 21:50 ` [PATCH 13/15] perf trace: Make --(min,max}-stack imply "--call-graph dwarf" Arnaldo Carvalho de Melo
2016-04-15 21:51 ` [PATCH 14/15] perf evlist: Expose perf_event_mlock_kb_in_pages() helper Arnaldo Carvalho de Melo
2016-04-15 21:51 ` [PATCH 15/15] perf trace: Bump --mmap-pages when --call-graph is used by the root user Arnaldo Carvalho de Melo
2016-04-16  9:12 ` [GIT PULL 00/15] perf/core improvements Ingo Molnar
  -- strict thread matches above, loose matches on Subject: below --
2011-10-06 17:22 Arnaldo Carvalho de Melo
2011-10-10  5:11 ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).