All of lore.kernel.org
 help / color / mirror / Atom feed
* [GIT PULL 00/19] perf/core improvements
@ 2016-04-12  1:53 Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 01/19] perf script: Use readdir() instead of deprecated readdir_r() Arnaldo Carvalho de Melo
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Adrian Hunter,
	David Ahern, Jiri Olsa, Milian Wolff, Namhyung Kim, pi3orama,
	Wang Nan, Zefan Li, Arnaldo Carvalho de Melo

Hi Ingo,

	Please consider pulling, tested with 'perf test', 'make -C tools/perf
build-test' and building on these userspaces, using docker:

  # dm
  alldeps-fedora-rawhide-minus-python-dev: Ok
  alldeps-fedora-20: Ok
  alldeps-ubuntu-12.04: Ok
  minimal-debian-experimental-x-mips64: Ok
  minimal-debian-experimental-x-mips64el: Ok
  minimal-debian-experimental-x-mipsel: Ok
  minimal-ubuntu-x-arm: Ok
  minimal-ubuntu-x-arm64: Ok
  minimal-ubuntu-x-ppc64: Ok
  minimal-ubuntu-x-ppc64el: Ok
  alldeps-debian: Ok
  alldeps-mageia: Ok
  alldeps-rhel7: Ok
  alldeps-centos: Ok
  alldeps-opensuse: Ok
  alldeps-ubuntu: Ok
  #

	This is on top of my previous pull request, that is not yet
merged: perf-core-for-mingo-20160408.

Best regards,

- Arnaldo

The following changes since commit 99e87f7bb7268cf644add87130590966fd5d0d17:

  perf symbols: Adjust symbol for shared objects (2016-04-08 09:58:15 -0300)

are available in the git repository at:

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

for you to fetch changes up to 00768a2bd3245eace0690fcf2c02776a256b66d7:

  perf trace: Print unresolved symbol names as addresses (2016-04-11 22:18:25 -0300)

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

- Automagically create a 'bpf-output' event, easing the setup of BPF
  C "scripts" that produce output via the perf ring buffer. Now it is
  just a matter of calling any perf tool, such as 'trace', with a C
  source file that references the __bpf_stdout__ output channel and
  that channel will be created and connected to the script:

  # trace -e nanosleep --event test_bpf_stdout.c usleep 1
    0.013 ( 0.013 ms): usleep/2818 nanosleep(rqtp: 0x7ffcead45f40                                        ) ...
    0.013 (         ): __bpf_stdout__:Raise a BPF event!..)
    0.015 (         ): perf_bpf_probe:func_begin:(ffffffff81112460))
    0.261 (         ): __bpf_stdout__:Raise a BPF event!..)
    0.262 (         ): perf_bpf_probe:func_end:(ffffffff81112460 <- ffffffff81003d92))
    0.264 ( 0.264 ms): usleep/2818  ... [continued]: nanosleep()) = 0
  #

  Further work is needed to reduce the number of lines in a perf bpf C source
  file, this being the part where we greatly reduce the command line setup (Wang Nan)

- 'perf trace' now supports callchains, with 'trace --call-graph dwarf' using
  libunwind, just like 'perf top', to ask the kernel for stack dumps for CFI
  processing. This reduces the overhead by asking just for userspace callchains
  and also only for the syscall exit tracepoint (raw_syscalls:sys_exit)
  (Milian Wolff, Arnaldo Carvalho de Melo)

  Try it with, for instance:

     # perf trace --call dwarf ping 127.0.0.1

  An excerpt of a system wide 'perf trace --call dwarf" session is at:

   https://fedorapeople.org/~acme/perf/perf-trace--call-graph-dwarf--all-cpus.txt

  You may need to bump the number of mmap pages, using -m/--mmap-pages,
  but on a Broadwell machine the defaults allowed system wide tracing to
  work without losing that many records, experiment with just some
  syscalls, like:

    # perf trace --call dwarf -e nanosleep,futex

  All the targets available for 'perf record', 'perf top' (--pid, --tid, --cpu,
  etc) should work. Also --duration may be interesting to try.

  To get filenames from in various syscalls pointer args (open, ettc), add this
  to the mix:

  # perf probe 'vfs_getname=getname_flags:72 pathname=filename:string'

  Making this work is next in line:

     # trace --call dwarf --ev sched:sched_switch/call-graph=fp/ usleep 1

  I.e. honouring per-tracepoint callchains in 'perf trace' in addition to
  in raw_syscalls:sys_exit.

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

----------------------------------------------------------------
Arnaldo Carvalho de Melo (15):
      perf script: Use readdir() instead of deprecated readdir_r()
      perf thread_map: Use readdir() instead of deprecated readdir_r()
      perf tools: Use readdir() instead of deprecated readdir_r()
      perf tools: Use readdir() instead of deprecated readdir_r()
      perf dwarf: Guard !x86_64 definitions under #ifdef else clause
      perf evsel: Allow passing a left alignment when printing a symbol
      perf evsel: Rename print_ip() to fprintf_sym()
      perf evsel: Introduce fprintf_callchain() method out of fprintf_sym()
      perf trace: Exclude the kernel part of the callchain leading to a syscall
      perf evsel: Do not use globals in config()
      perf evlist: Add (reset,set)_sample_bit methods
      perf evsel: Rename config_callgraph() to config_callchain() and make it public
      perf trace: Make "--call-graph" affect just "raw_syscalls:sys_exit"
      perf evsel: Allow unresolved symbol names to be printed as addresses
      perf trace: Print unresolved symbol names as addresses

Milian Wolff (2):
      perf evsel: Allow specifying a file to output in perf_evsel__print_ip
      perf trace: Add support for printing call chains on sys_exit events.

Wang Nan (2):
      perf bpf: Clone bpf stdout events in multiple bpf scripts
      perf bpf: Automatically create bpf-output event __bpf_stdout__

 tools/perf/Documentation/perf-trace.txt      |   9 ++
 tools/perf/arch/x86/tests/perf-time-to-tsc.c |   2 +-
 tools/perf/arch/x86/util/dwarf-regs.c        |   8 +-
 tools/perf/builtin-kvm.c                     |   2 +-
 tools/perf/builtin-record.c                  |  10 +-
 tools/perf/builtin-script.c                  |  78 +++++++--------
 tools/perf/builtin-top.c                     |   2 +-
 tools/perf/builtin-trace.c                   |  65 +++++++++++-
 tools/perf/tests/bpf.c                       |   2 +-
 tools/perf/tests/code-reading.c              |   2 +-
 tools/perf/tests/keep-tracking.c             |   2 +-
 tools/perf/tests/openat-syscall-tp-fields.c  |   2 +-
 tools/perf/tests/perf-record.c               |   2 +-
 tools/perf/tests/switch-tracking.c           |   2 +-
 tools/perf/util/bpf-loader.c                 | 143 +++++++++++++++++++++++++++
 tools/perf/util/bpf-loader.h                 |  19 ++++
 tools/perf/util/event.c                      |  12 +--
 tools/perf/util/evlist.c                     |  18 ++++
 tools/perf/util/evlist.h                     |  16 ++-
 tools/perf/util/evsel.c                      |  16 +--
 tools/perf/util/evsel.h                      |  14 ++-
 tools/perf/util/parse-events.c               |  60 +++++------
 tools/perf/util/record.c                     |   5 +-
 tools/perf/util/session.c                    |  95 ++++++++++++------
 tools/perf/util/session.h                    |   8 +-
 tools/perf/util/symbol.c                     |  25 ++++-
 tools/perf/util/symbol.h                     |   6 ++
 tools/perf/util/thread_map.c                 |   8 +-
 28 files changed, 487 insertions(+), 146 deletions(-)

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

* [PATCH 01/19] perf script: Use readdir() instead of deprecated readdir_r()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 02/19] perf thread_map: " Arnaldo Carvalho de Melo
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The readdir() function is thread safe as long as just one thread uses a
DIR, which is the case in 'perf script', so, to avoid breaking the build
with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().

See: http://man7.org/linux/man-pages/man3/readdir.3.html

"However, in modern implementations (including the glibc implementation),
concurrent calls to readdir() that specify different directory streams
are thread-safe.  In cases where multiple threads must read from the
same directory stream, using readdir() with external synchronization is
still preferable to the use of the deprecated readdir_r(3) function."

Noticed while building on a Fedora Rawhide docker container.

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-mt3xz7n2hl49ni2vx7kuq74g@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-script.c | 70 ++++++++++++++++++++++-----------------------
 1 file changed, 34 insertions(+), 36 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 59009aa7e2ca..8f6ab2ac855a 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1415,21 +1415,19 @@ static int is_directory(const char *base_path, const struct dirent *dent)
 	return S_ISDIR(st.st_mode);
 }
 
-#define for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next)\
-	while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) &&	\
-	       lang_next)						\
-		if ((lang_dirent.d_type == DT_DIR ||			\
-		     (lang_dirent.d_type == DT_UNKNOWN &&		\
-		      is_directory(scripts_path, &lang_dirent))) &&	\
-		    (strcmp(lang_dirent.d_name, ".")) &&		\
-		    (strcmp(lang_dirent.d_name, "..")))
-
-#define for_each_script(lang_path, lang_dir, script_dirent, script_next)\
-	while (!readdir_r(lang_dir, &script_dirent, &script_next) &&	\
-	       script_next)						\
-		if (script_dirent.d_type != DT_DIR &&			\
-		    (script_dirent.d_type != DT_UNKNOWN ||		\
-		     !is_directory(lang_path, &script_dirent)))
+#define for_each_lang(scripts_path, scripts_dir, lang_dirent)		\
+	while ((lang_dirent = readdir(scripts_dir)) != NULL)		\
+		if ((lang_dirent->d_type == DT_DIR ||			\
+		     (lang_dirent->d_type == DT_UNKNOWN &&		\
+		      is_directory(scripts_path, lang_dirent))) &&	\
+		    (strcmp(lang_dirent->d_name, ".")) &&		\
+		    (strcmp(lang_dirent->d_name, "..")))
+
+#define for_each_script(lang_path, lang_dir, script_dirent)		\
+	while ((script_dirent = readdir(lang_dir)) != NULL)		\
+		if (script_dirent->d_type != DT_DIR &&			\
+		    (script_dirent->d_type != DT_UNKNOWN ||		\
+		     !is_directory(lang_path, script_dirent)))
 
 
 #define RECORD_SUFFIX			"-record"
@@ -1575,7 +1573,7 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
 				  const char *s __maybe_unused,
 				  int unset __maybe_unused)
 {
-	struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+	struct dirent *script_dirent, *lang_dirent;
 	char scripts_path[MAXPATHLEN];
 	DIR *scripts_dir, *lang_dir;
 	char script_path[MAXPATHLEN];
@@ -1590,19 +1588,19 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
 	if (!scripts_dir)
 		return -1;
 
-	for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
 		snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
-			 lang_dirent.d_name);
+			 lang_dirent->d_name);
 		lang_dir = opendir(lang_path);
 		if (!lang_dir)
 			continue;
 
-		for_each_script(lang_path, lang_dir, script_dirent, script_next) {
-			script_root = get_script_root(&script_dirent, REPORT_SUFFIX);
+		for_each_script(lang_path, lang_dir, script_dirent) {
+			script_root = get_script_root(script_dirent, REPORT_SUFFIX);
 			if (script_root) {
 				desc = script_desc__findnew(script_root);
 				snprintf(script_path, MAXPATHLEN, "%s/%s",
-					 lang_path, script_dirent.d_name);
+					 lang_path, script_dirent->d_name);
 				read_script_info(desc, script_path);
 				free(script_root);
 			}
@@ -1690,7 +1688,7 @@ static int check_ev_match(char *dir_name, char *scriptname,
  */
 int find_scripts(char **scripts_array, char **scripts_path_array)
 {
-	struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+	struct dirent *script_dirent, *lang_dirent;
 	char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
 	DIR *scripts_dir, *lang_dir;
 	struct perf_session *session;
@@ -1713,9 +1711,9 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
 		return -1;
 	}
 
-	for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
 		snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
-			 lang_dirent.d_name);
+			 lang_dirent->d_name);
 #ifdef NO_LIBPERL
 		if (strstr(lang_path, "perl"))
 			continue;
@@ -1729,16 +1727,16 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
 		if (!lang_dir)
 			continue;
 
-		for_each_script(lang_path, lang_dir, script_dirent, script_next) {
+		for_each_script(lang_path, lang_dir, script_dirent) {
 			/* Skip those real time scripts: xxxtop.p[yl] */
-			if (strstr(script_dirent.d_name, "top."))
+			if (strstr(script_dirent->d_name, "top."))
 				continue;
 			sprintf(scripts_path_array[i], "%s/%s", lang_path,
-				script_dirent.d_name);
-			temp = strchr(script_dirent.d_name, '.');
+				script_dirent->d_name);
+			temp = strchr(script_dirent->d_name, '.');
 			snprintf(scripts_array[i],
-				(temp - script_dirent.d_name) + 1,
-				"%s", script_dirent.d_name);
+				(temp - script_dirent->d_name) + 1,
+				"%s", script_dirent->d_name);
 
 			if (check_ev_match(lang_path,
 					scripts_array[i], session))
@@ -1756,7 +1754,7 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
 
 static char *get_script_path(const char *script_root, const char *suffix)
 {
-	struct dirent *script_next, *lang_next, script_dirent, lang_dirent;
+	struct dirent *script_dirent, *lang_dirent;
 	char scripts_path[MAXPATHLEN];
 	char script_path[MAXPATHLEN];
 	DIR *scripts_dir, *lang_dir;
@@ -1769,21 +1767,21 @@ static char *get_script_path(const char *script_root, const char *suffix)
 	if (!scripts_dir)
 		return NULL;
 
-	for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) {
+	for_each_lang(scripts_path, scripts_dir, lang_dirent) {
 		snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,
-			 lang_dirent.d_name);
+			 lang_dirent->d_name);
 		lang_dir = opendir(lang_path);
 		if (!lang_dir)
 			continue;
 
-		for_each_script(lang_path, lang_dir, script_dirent, script_next) {
-			__script_root = get_script_root(&script_dirent, suffix);
+		for_each_script(lang_path, lang_dir, script_dirent) {
+			__script_root = get_script_root(script_dirent, suffix);
 			if (__script_root && !strcmp(script_root, __script_root)) {
 				free(__script_root);
 				closedir(lang_dir);
 				closedir(scripts_dir);
 				snprintf(script_path, MAXPATHLEN, "%s/%s",
-					 lang_path, script_dirent.d_name);
+					 lang_path, script_dirent->d_name);
 				return strdup(script_path);
 			}
 			free(__script_root);
-- 
2.5.5

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

* [PATCH 02/19] perf thread_map: Use readdir() instead of deprecated readdir_r()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 01/19] perf script: Use readdir() instead of deprecated readdir_r() Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 03/19] perf tools: " Arnaldo Carvalho de Melo
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The readdir() function is thread safe as long as just one thread uses a
DIR, which is the case in thread_map, so, to avoid breaking the build
with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().

See: http://man7.org/linux/man-pages/man3/readdir.3.html

"However, in modern implementations (including the glibc implementation),
concurrent calls to readdir() that specify different directory streams
are thread-safe.  In cases where multiple threads must read from the
same directory stream, using readdir() with external synchronization is
still preferable to the use of the deprecated readdir_r(3) function."

Noticed while building on a Fedora Rawhide docker container.

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-del8h2a0f40z75j4r42l96l0@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/thread_map.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 08afc6909953..267112b4e3db 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -94,7 +94,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
 	DIR *proc;
 	int max_threads = 32, items, i;
 	char path[256];
-	struct dirent dirent, *next, **namelist = NULL;
+	struct dirent *dirent, **namelist = NULL;
 	struct thread_map *threads = thread_map__alloc(max_threads);
 
 	if (threads == NULL)
@@ -107,16 +107,16 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
 	threads->nr = 0;
 	atomic_set(&threads->refcnt, 1);
 
-	while (!readdir_r(proc, &dirent, &next) && next) {
+	while ((dirent = readdir(proc)) != NULL) {
 		char *end;
 		bool grow = false;
 		struct stat st;
-		pid_t pid = strtol(dirent.d_name, &end, 10);
+		pid_t pid = strtol(dirent->d_name, &end, 10);
 
 		if (*end) /* only interested in proper numerical dirents */
 			continue;
 
-		snprintf(path, sizeof(path), "/proc/%s", dirent.d_name);
+		snprintf(path, sizeof(path), "/proc/%s", dirent->d_name);
 
 		if (stat(path, &st) != 0)
 			continue;
-- 
2.5.5

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

* [PATCH 03/19] perf tools: Use readdir() instead of deprecated readdir_r()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 01/19] perf script: Use readdir() instead of deprecated readdir_r() Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 02/19] perf thread_map: " Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 04/19] " Arnaldo Carvalho de Melo
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The readdir() function is thread safe as long as just one thread uses a
DIR, which is the case when synthesizing events for pre-existing threads
by traversing /proc, so, to avoid breaking the build with glibc-2.23.90
(upcoming 2.24), use it instead of readdir_r().

See: http://man7.org/linux/man-pages/man3/readdir.3.html

"However, in modern implementations (including the glibc implementation),
concurrent calls to readdir() that specify different directory streams
are thread-safe.  In cases where multiple threads must read from the
same directory stream, using readdir() with external synchronization is
still preferable to the use of the deprecated readdir_r(3) function."

Noticed while building on a Fedora Rawhide docker container.

   CC       /tmp/build/perf/util/event.o
  util/event.c: In function '__event__synthesize_thread':
  util/event.c:466:2: error: 'readdir_r' is deprecated [-Werror=deprecated-declarations]
    while (!readdir_r(tasks, &dirent, &next) && next) {
    ^~~~~
  In file included from /usr/include/features.h:368:0,
                   from /usr/include/stdint.h:25,
                   from /usr/lib/gcc/x86_64-redhat-linux/6.0.0/include/stdint.h:9,
                   from /git/linux/tools/include/linux/types.h:6,
                   from util/event.c:1:
  /usr/include/dirent.h:189:12: note: declared here

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-i1vj7nyjp2p750rirxgrfd3c@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/event.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index b68959037688..f6fcc6832949 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -434,7 +434,7 @@ static int __event__synthesize_thread(union perf_event *comm_event,
 {
 	char filename[PATH_MAX];
 	DIR *tasks;
-	struct dirent dirent, *next;
+	struct dirent *dirent;
 	pid_t tgid, ppid;
 	int rc = 0;
 
@@ -463,11 +463,11 @@ static int __event__synthesize_thread(union perf_event *comm_event,
 		return 0;
 	}
 
-	while (!readdir_r(tasks, &dirent, &next) && next) {
+	while ((dirent = readdir(tasks)) != NULL) {
 		char *end;
 		pid_t _pid;
 
-		_pid = strtol(dirent.d_name, &end, 10);
+		_pid = strtol(dirent->d_name, &end, 10);
 		if (*end)
 			continue;
 
@@ -576,7 +576,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
 {
 	DIR *proc;
 	char proc_path[PATH_MAX];
-	struct dirent dirent, *next;
+	struct dirent *dirent;
 	union perf_event *comm_event, *mmap_event, *fork_event;
 	int err = -1;
 
@@ -601,9 +601,9 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
 	if (proc == NULL)
 		goto out_free_fork;
 
-	while (!readdir_r(proc, &dirent, &next) && next) {
+	while ((dirent = readdir(proc)) != NULL) {
 		char *end;
-		pid_t pid = strtol(dirent.d_name, &end, 10);
+		pid_t pid = strtol(dirent->d_name, &end, 10);
 
 		if (*end) /* only interested in proper numerical dirents */
 			continue;
-- 
2.5.5

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

* [PATCH 04/19] perf tools: Use readdir() instead of deprecated readdir_r()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (2 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 03/19] perf tools: " Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 05/19] perf dwarf: Guard !x86_64 definitions under #ifdef else clause Arnaldo Carvalho de Melo
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The readdir() function is thread safe as long as just one thread uses a
DIR, which is the case when parsing tracepoint event definitions, to
avoid breaking the build with glibc-2.23.90 (upcoming 2.24), use it
instead of readdir_r().

See: http://man7.org/linux/man-pages/man3/readdir.3.html

"However, in modern implementations (including the glibc implementation),
concurrent calls to readdir() that specify different directory streams
are thread-safe.  In cases where multiple threads must read from the
same directory stream, using readdir() with external synchronization is
still preferable to the use of the deprecated readdir_r(3) function."

Noticed while building on a Fedora Rawhide docker container.

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-wddn49r6bz6wq4ee3dxbl7lo@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/parse-events.c | 60 +++++++++++++++++++++---------------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 4c19d5e79d8c..bcbc983d4b12 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -138,11 +138,11 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = {
 #define PERF_EVENT_TYPE(config)		__PERF_EVENT_FIELD(config, TYPE)
 #define PERF_EVENT_ID(config)		__PERF_EVENT_FIELD(config, EVENT)
 
-#define for_each_subsystem(sys_dir, sys_dirent, sys_next)	       \
-	while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next)	       \
-	if (sys_dirent.d_type == DT_DIR &&				       \
-	   (strcmp(sys_dirent.d_name, ".")) &&				       \
-	   (strcmp(sys_dirent.d_name, "..")))
+#define for_each_subsystem(sys_dir, sys_dirent)			\
+	while ((sys_dirent = readdir(sys_dir)) != NULL)		\
+		if (sys_dirent->d_type == DT_DIR &&		\
+		    (strcmp(sys_dirent->d_name, ".")) &&	\
+		    (strcmp(sys_dirent->d_name, "..")))
 
 static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
 {
@@ -159,12 +159,12 @@ static int tp_event_has_id(struct dirent *sys_dir, struct dirent *evt_dir)
 	return 0;
 }
 
-#define for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next)	       \
-	while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next)        \
-	if (evt_dirent.d_type == DT_DIR &&				       \
-	   (strcmp(evt_dirent.d_name, ".")) &&				       \
-	   (strcmp(evt_dirent.d_name, "..")) &&				       \
-	   (!tp_event_has_id(&sys_dirent, &evt_dirent)))
+#define for_each_event(sys_dirent, evt_dir, evt_dirent)		\
+	while ((evt_dirent = readdir(evt_dir)) != NULL)		\
+		if (evt_dirent->d_type == DT_DIR &&		\
+		    (strcmp(evt_dirent->d_name, ".")) &&	\
+		    (strcmp(evt_dirent->d_name, "..")) &&	\
+		    (!tp_event_has_id(sys_dirent, evt_dirent)))
 
 #define MAX_EVENT_LENGTH 512
 
@@ -173,7 +173,7 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
 {
 	struct tracepoint_path *path = NULL;
 	DIR *sys_dir, *evt_dir;
-	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+	struct dirent *sys_dirent, *evt_dirent;
 	char id_buf[24];
 	int fd;
 	u64 id;
@@ -184,18 +184,18 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
 	if (!sys_dir)
 		return NULL;
 
-	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+	for_each_subsystem(sys_dir, sys_dirent) {
 
 		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
-			 sys_dirent.d_name);
+			 sys_dirent->d_name);
 		evt_dir = opendir(dir_path);
 		if (!evt_dir)
 			continue;
 
-		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+		for_each_event(sys_dirent, evt_dir, evt_dirent) {
 
 			snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path,
-				 evt_dirent.d_name);
+				 evt_dirent->d_name);
 			fd = open(evt_path, O_RDONLY);
 			if (fd < 0)
 				continue;
@@ -220,9 +220,9 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
 					free(path);
 					return NULL;
 				}
-				strncpy(path->system, sys_dirent.d_name,
+				strncpy(path->system, sys_dirent->d_name,
 					MAX_EVENT_LENGTH);
-				strncpy(path->name, evt_dirent.d_name,
+				strncpy(path->name, evt_dirent->d_name,
 					MAX_EVENT_LENGTH);
 				return path;
 			}
@@ -1812,7 +1812,7 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob,
 			     bool name_only)
 {
 	DIR *sys_dir, *evt_dir;
-	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+	struct dirent *sys_dirent, *evt_dirent;
 	char evt_path[MAXPATHLEN];
 	char dir_path[MAXPATHLEN];
 	char **evt_list = NULL;
@@ -1830,20 +1830,20 @@ restart:
 			goto out_close_sys_dir;
 	}
 
-	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+	for_each_subsystem(sys_dir, sys_dirent) {
 		if (subsys_glob != NULL &&
-		    !strglobmatch(sys_dirent.d_name, subsys_glob))
+		    !strglobmatch(sys_dirent->d_name, subsys_glob))
 			continue;
 
 		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
-			 sys_dirent.d_name);
+			 sys_dirent->d_name);
 		evt_dir = opendir(dir_path);
 		if (!evt_dir)
 			continue;
 
-		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+		for_each_event(sys_dirent, evt_dir, evt_dirent) {
 			if (event_glob != NULL &&
-			    !strglobmatch(evt_dirent.d_name, event_glob))
+			    !strglobmatch(evt_dirent->d_name, event_glob))
 				continue;
 
 			if (!evt_num_known) {
@@ -1852,7 +1852,7 @@ restart:
 			}
 
 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
-				 sys_dirent.d_name, evt_dirent.d_name);
+				 sys_dirent->d_name, evt_dirent->d_name);
 
 			evt_list[evt_i] = strdup(evt_path);
 			if (evt_list[evt_i] == NULL)
@@ -1905,7 +1905,7 @@ out_close_sys_dir:
 int is_valid_tracepoint(const char *event_string)
 {
 	DIR *sys_dir, *evt_dir;
-	struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent;
+	struct dirent *sys_dirent, *evt_dirent;
 	char evt_path[MAXPATHLEN];
 	char dir_path[MAXPATHLEN];
 
@@ -1913,17 +1913,17 @@ int is_valid_tracepoint(const char *event_string)
 	if (!sys_dir)
 		return 0;
 
-	for_each_subsystem(sys_dir, sys_dirent, sys_next) {
+	for_each_subsystem(sys_dir, sys_dirent) {
 
 		snprintf(dir_path, MAXPATHLEN, "%s/%s", tracing_events_path,
-			 sys_dirent.d_name);
+			 sys_dirent->d_name);
 		evt_dir = opendir(dir_path);
 		if (!evt_dir)
 			continue;
 
-		for_each_event(sys_dirent, evt_dir, evt_dirent, evt_next) {
+		for_each_event(sys_dirent, evt_dir, evt_dirent) {
 			snprintf(evt_path, MAXPATHLEN, "%s:%s",
-				 sys_dirent.d_name, evt_dirent.d_name);
+				 sys_dirent->d_name, evt_dirent->d_name);
 			if (!strcmp(evt_path, event_string)) {
 				closedir(evt_dir);
 				closedir(sys_dir);
-- 
2.5.5

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

* [PATCH 05/19] perf dwarf: Guard !x86_64 definitions under #ifdef else clause
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (3 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 04/19] " Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 06/19] perf bpf: Clone bpf stdout events in multiple bpf scripts Arnaldo Carvalho de Melo
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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 fix the build on Fedora Rawhide (gcc 6.0.0 20160311 (Red Hat 6.0.0-0.17):

    CC       /tmp/build/perf/arch/x86/util/dwarf-regs.o
  arch/x86/util/dwarf-regs.c:66:36: error: 'x86_32_regoffset_table' defined but not used [-Werror=unused-const-variable=]
   static const struct pt_regs_offset x86_32_regoffset_table[] = {
                                      ^~~~~~~~~~~~~~~~~~~~~~
  cc1: all warnings being treated as errors

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-fghuksc1u8ln82bof4lwcj0o@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/util/dwarf-regs.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/perf/arch/x86/util/dwarf-regs.c b/tools/perf/arch/x86/util/dwarf-regs.c
index 9223c164e545..1f86ee8fb831 100644
--- a/tools/perf/arch/x86/util/dwarf-regs.c
+++ b/tools/perf/arch/x86/util/dwarf-regs.c
@@ -63,6 +63,8 @@ struct pt_regs_offset {
 # define REG_OFFSET_NAME_32(n, r) {.name = n, .offset = offsetof(struct pt_regs, r)}
 #endif
 
+/* TODO: switching by dwarf address size */
+#ifndef __x86_64__
 static const struct pt_regs_offset x86_32_regoffset_table[] = {
 	REG_OFFSET_NAME_32("%ax",	eax),
 	REG_OFFSET_NAME_32("%cx",	ecx),
@@ -75,6 +77,8 @@ static const struct pt_regs_offset x86_32_regoffset_table[] = {
 	REG_OFFSET_END,
 };
 
+#define regoffset_table x86_32_regoffset_table
+#else
 static const struct pt_regs_offset x86_64_regoffset_table[] = {
 	REG_OFFSET_NAME_64("%ax",	rax),
 	REG_OFFSET_NAME_64("%dx",	rdx),
@@ -95,11 +99,7 @@ static const struct pt_regs_offset x86_64_regoffset_table[] = {
 	REG_OFFSET_END,
 };
 
-/* TODO: switching by dwarf address size */
-#ifdef __x86_64__
 #define regoffset_table x86_64_regoffset_table
-#else
-#define regoffset_table x86_32_regoffset_table
 #endif
 
 /* Minus 1 for the ending REG_OFFSET_END */
-- 
2.5.5

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

* [PATCH 06/19] perf bpf: Clone bpf stdout events in multiple bpf scripts
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (4 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 05/19] perf dwarf: Guard !x86_64 definitions under #ifdef else clause Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 07/19] perf bpf: Automatically create bpf-output event __bpf_stdout__ Arnaldo Carvalho de Melo
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Wang Nan, Jiri Olsa, Zefan Li, pi3orama,
	Arnaldo Carvalho de Melo

From: Wang Nan <wangnan0@huawei.com>

This patch allows cloning bpf-output event configuration among multiple
bpf scripts. If there exist a map named '__bpf_output__' and not
configured using 'map:__bpf_output__.event=', this patch clones the
configuration of another '__bpf_stdout__' map. For example, following
command:

  # perf trace --ev bpf-output/no-inherit,name=evt/ \
               --ev ./test_bpf_trace.c/map:__bpf_stdout__.event=evt/ \
               --ev ./test_bpf_trace2.c usleep 100000

equals to:

  # perf trace --ev bpf-output/no-inherit,name=evt/ \
               --ev ./test_bpf_trace.c/map:__bpf_stdout__.event=evt/  \
               --ev ./test_bpf_trace2.c/map:__bpf_stdout__.event=evt/ \
               usleep 100000

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1460128045-97310-4-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-record.c  |   8 +++
 tools/perf/builtin-trace.c   |   7 +++
 tools/perf/util/bpf-loader.c | 124 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/bpf-loader.h |  19 +++++++
 4 files changed, 158 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 410035c6e300..e64bd1ee5acb 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -1276,6 +1276,14 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
 	if (err)
 		return err;
 
+	err = bpf__setup_stdout(rec->evlist);
+	if (err) {
+		bpf__strerror_setup_stdout(rec->evlist, err, errbuf, sizeof(errbuf));
+		pr_err("ERROR: Setup BPF stdout failed: %s\n",
+			 errbuf);
+		return err;
+	}
+
 	err = -ENOMEM;
 
 	symbol__init(NULL);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 11290b57ce04..27d987030627 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -3273,6 +3273,13 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
 				 trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
 
+	err = bpf__setup_stdout(trace.evlist);
+	if (err) {
+		bpf__strerror_setup_stdout(trace.evlist, err, bf, sizeof(bf));
+		pr_err("ERROR: Setup BPF stdout failed: %s\n", bf);
+		goto out;
+	}
+
 	if (trace.trace_pgfaults) {
 		trace.opts.sample_address = true;
 		trace.opts.sample_time = true;
diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 0967ce601931..67f61a902a08 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -842,6 +842,58 @@ bpf_map_op__new(struct parse_events_term *term)
 	return op;
 }
 
+static struct bpf_map_op *
+bpf_map_op__clone(struct bpf_map_op *op)
+{
+	struct bpf_map_op *newop;
+
+	newop = memdup(op, sizeof(*op));
+	if (!newop) {
+		pr_debug("Failed to alloc bpf_map_op\n");
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&newop->list);
+	if (op->key_type == BPF_MAP_KEY_RANGES) {
+		size_t memsz = op->k.array.nr_ranges *
+			       sizeof(op->k.array.ranges[0]);
+
+		newop->k.array.ranges = memdup(op->k.array.ranges, memsz);
+		if (!newop->k.array.ranges) {
+			pr_debug("Failed to alloc indices for map\n");
+			free(newop);
+			return NULL;
+		}
+	}
+
+	return newop;
+}
+
+static struct bpf_map_priv *
+bpf_map_priv__clone(struct bpf_map_priv *priv)
+{
+	struct bpf_map_priv *newpriv;
+	struct bpf_map_op *pos, *newop;
+
+	newpriv = zalloc(sizeof(*newpriv));
+	if (!newpriv) {
+		pr_debug("No enough memory to alloc map private\n");
+		return NULL;
+	}
+	INIT_LIST_HEAD(&newpriv->ops_list);
+
+	list_for_each_entry(pos, &priv->ops_list, list) {
+		newop = bpf_map_op__clone(pos);
+		if (!newop) {
+			bpf_map_priv__purge(newpriv);
+			return NULL;
+		}
+		list_add_tail(&newop->list, &newpriv->ops_list);
+	}
+
+	return newpriv;
+}
+
 static int
 bpf_map__add_op(struct bpf_map *map, struct bpf_map_op *op)
 {
@@ -1417,6 +1469,70 @@ int bpf__apply_obj_config(void)
 	return 0;
 }
 
+#define bpf__for_each_map(pos, obj, objtmp)	\
+	bpf_object__for_each_safe(obj, objtmp)	\
+		bpf_map__for_each(pos, obj)
+
+#define bpf__for_each_stdout_map(pos, obj, objtmp)	\
+	bpf__for_each_map(pos, obj, objtmp) 		\
+		if (bpf_map__get_name(pos) && 		\
+			(strcmp("__bpf_stdout__", 	\
+				bpf_map__get_name(pos)) == 0))
+
+int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
+{
+	struct bpf_map_priv *tmpl_priv = NULL;
+	struct bpf_object *obj, *tmp;
+	struct bpf_map *map;
+	int err;
+	bool need_init = false;
+
+	bpf__for_each_stdout_map(map, obj, tmp) {
+		struct bpf_map_priv *priv;
+
+		err = bpf_map__get_private(map, (void **)&priv);
+		if (err)
+			return -BPF_LOADER_ERRNO__INTERNAL;
+
+		/*
+		 * No need to check map type: type should have been
+		 * verified by kernel.
+		 */
+		if (!need_init && !priv)
+			need_init = !priv;
+		if (!tmpl_priv && priv)
+			tmpl_priv = priv;
+	}
+
+	if (!need_init)
+		return 0;
+
+	if (!tmpl_priv)
+		return 0;
+
+	bpf__for_each_stdout_map(map, obj, tmp) {
+		struct bpf_map_priv *priv;
+
+		err = bpf_map__get_private(map, (void **)&priv);
+		if (err)
+			return -BPF_LOADER_ERRNO__INTERNAL;
+		if (priv)
+			continue;
+
+		priv = bpf_map_priv__clone(tmpl_priv);
+		if (!priv)
+			return -ENOMEM;
+
+		err = bpf_map__set_private(map, priv, bpf_map_priv__clear);
+		if (err) {
+			bpf_map_priv__clear(map, priv);
+			return err;
+		}
+	}
+
+	return 0;
+}
+
 #define ERRNO_OFFSET(e)		((e) - __BPF_LOADER_ERRNO__START)
 #define ERRCODE_OFFSET(c)	ERRNO_OFFSET(BPF_LOADER_ERRNO__##c)
 #define NR_ERRNO	(__BPF_LOADER_ERRNO__END - __BPF_LOADER_ERRNO__START)
@@ -1590,3 +1706,11 @@ int bpf__strerror_apply_obj_config(int err, char *buf, size_t size)
 	bpf__strerror_end(buf, size);
 	return 0;
 }
+
+int bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
+			       int err, char *buf, size_t size)
+{
+	bpf__strerror_head(err, buf, size);
+	bpf__strerror_end(buf, size);
+	return 0;
+}
diff --git a/tools/perf/util/bpf-loader.h b/tools/perf/util/bpf-loader.h
index be4311944e3d..941e17275aa7 100644
--- a/tools/perf/util/bpf-loader.h
+++ b/tools/perf/util/bpf-loader.h
@@ -79,6 +79,11 @@ int bpf__strerror_config_obj(struct bpf_object *obj,
 			     size_t size);
 int bpf__apply_obj_config(void);
 int bpf__strerror_apply_obj_config(int err, char *buf, size_t size);
+
+int bpf__setup_stdout(struct perf_evlist *evlist);
+int bpf__strerror_setup_stdout(struct perf_evlist *evlist, int err,
+			       char *buf, size_t size);
+
 #else
 static inline struct bpf_object *
 bpf__prepare_load(const char *filename __maybe_unused,
@@ -125,6 +130,12 @@ bpf__apply_obj_config(void)
 }
 
 static inline int
+bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
+{
+	return 0;
+}
+
+static inline int
 __bpf_strerror(char *buf, size_t size)
 {
 	if (!size)
@@ -177,5 +188,13 @@ bpf__strerror_apply_obj_config(int err __maybe_unused,
 {
 	return __bpf_strerror(buf, size);
 }
+
+static inline int
+bpf__strerror_setup_stdout(struct perf_evlist *evlist __maybe_unused,
+			   int err __maybe_unused, char *buf,
+			   size_t size)
+{
+	return __bpf_strerror(buf, size);
+}
 #endif
 #endif
-- 
2.5.5

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

* [PATCH 07/19] perf bpf: Automatically create bpf-output event __bpf_stdout__
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (5 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 06/19] perf bpf: Clone bpf stdout events in multiple bpf scripts Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 08/19] perf evsel: Allow specifying a file to output in perf_evsel__print_ip Arnaldo Carvalho de Melo
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Wang Nan, Jiri Olsa, Zefan Li, pi3orama,
	Arnaldo Carvalho de Melo

From: Wang Nan <wangnan0@huawei.com>

This patch removes the need to set a bpf-output event in cmdline.  By
referencing a map named '__bpf_stdout__', perf automatically creates an
event for it.

For example:

  # perf record -e ./test_bpf_trace.c usleep 100000
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.012 MB perf.data (2 samples) ]
  # perf script
           usleep  4639 [000] 261895.307826:        0            __bpf_stdout__:  ffffffff810eb9a1 ...
       BPF output: 0000: 52 61 69 73 65 20 61 20  Raise a
                   0008: 42 50 46 20 65 76 65 6e  BPF even
                   0010: 74 21 00 00              t!..
       BPF string: "Raise a BPF event!"

           usleep  4639 [000] 261895.407883:        0            __bpf_stdout__:  ffffffff8105d609 ...
       BPF output: 0000: 52 61 69 73 65 20 61 20  Raise a
                   0008: 42 50 46 20 65 76 65 6e  BPF even
                   0010: 74 21 00 00              t!..
       BPF string: "Raise a BPF event!"

  perf record -e ./test_bpf_trace.c usleep 100000

  equals to:

  perf record -e bpf-output/no-inherit=1,name=__bpf_stdout__/ \
              -e ./test_bpf_trace.c/map:__bpf_stdout__.event=__bpf_stdout__/ \
              usleep 100000

Where test_bpf_trace.c is:

  /************************ BEGIN **************************/
  #include <uapi/linux/bpf.h>
  struct bpf_map_def {
         unsigned int type;
         unsigned int key_size;
         unsigned int value_size;
         unsigned int max_entries;
  };
  #define SEC(NAME) __attribute__((section(NAME), used))
  static u64 (*ktime_get_ns)(void) =
         (void *)BPF_FUNC_ktime_get_ns;
  static int (*trace_printk)(const char *fmt, int fmt_size, ...) =
         (void *)BPF_FUNC_trace_printk;
  static int (*get_smp_processor_id)(void) =
         (void *)BPF_FUNC_get_smp_processor_id;
  static int (*perf_event_output)(void *, struct bpf_map_def *, int, void *, unsigned long) =
         (void *)BPF_FUNC_perf_event_output;

  struct bpf_map_def SEC("maps") __bpf_stdout__ = {
         .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
         .key_size = sizeof(int),
         .value_size = sizeof(u32),
         .max_entries = __NR_CPUS__,
  };

  static inline int __attribute__((always_inline))
  func(void *ctx, int type)
  {
	char output_str[] = "Raise a BPF event!";
	char err_str[] = "BAD %d\n";
	int err;

        err = perf_event_output(ctx, &__bpf_stdout__, get_smp_processor_id(),
			        &output_str, sizeof(output_str));
	if (err)
		trace_printk(err_str, sizeof(err_str), err);
        return 1;
  }
  SEC("func_begin=sys_nanosleep")
  int func_begin(void *ctx) {return func(ctx, 1);}
  SEC("func_end=sys_nanosleep%return")
  int func_end(void *ctx) { return func(ctx, 2);}
  char _license[] SEC("license") = "GPL";
  int _version SEC("version") = LINUX_VERSION_CODE;
  /************************* END ***************************/

Committer note:

Testing with 'perf trace':

  # trace -e nanosleep --ev test_bpf_stdout.c usleep 1
     0.007 ( 0.007 ms): usleep/729 nanosleep(rqtp: 0x7ffc5bbc5fe0) ...
     0.007 (         ): __bpf_stdout__:Raise a BPF event!..)
     0.008 (         ): perf_bpf_probe:func_begin:(ffffffff81112460))
     0.069 (         ): __bpf_stdout__:Raise a BPF event!..)
     0.070 (         ): perf_bpf_probe:func_end:(ffffffff81112460 <- ffffffff81003d92))
     0.072 ( 0.072 ms): usleep/729  ... [continued]: nanosleep()) = 0
  #

Suggested-and-Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1460128045-97310-5-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/bpf-loader.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index 67f61a902a08..493307d1414c 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -1483,6 +1483,7 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 {
 	struct bpf_map_priv *tmpl_priv = NULL;
 	struct bpf_object *obj, *tmp;
+	struct perf_evsel *evsel = NULL;
 	struct bpf_map *map;
 	int err;
 	bool need_init = false;
@@ -1507,8 +1508,16 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 	if (!need_init)
 		return 0;
 
-	if (!tmpl_priv)
-		return 0;
+	if (!tmpl_priv) {
+		err = parse_events(evlist, "bpf-output/no-inherit=1,name=__bpf_stdout__/",
+				   NULL);
+		if (err) {
+			pr_debug("ERROR: failed to create bpf-output event\n");
+			return -err;
+		}
+
+		evsel = perf_evlist__last(evlist);
+	}
 
 	bpf__for_each_stdout_map(map, obj, tmp) {
 		struct bpf_map_priv *priv;
@@ -1519,14 +1528,24 @@ int bpf__setup_stdout(struct perf_evlist *evlist __maybe_unused)
 		if (priv)
 			continue;
 
-		priv = bpf_map_priv__clone(tmpl_priv);
-		if (!priv)
-			return -ENOMEM;
+		if (tmpl_priv) {
+			priv = bpf_map_priv__clone(tmpl_priv);
+			if (!priv)
+				return -ENOMEM;
 
-		err = bpf_map__set_private(map, priv, bpf_map_priv__clear);
-		if (err) {
-			bpf_map_priv__clear(map, priv);
-			return err;
+			err = bpf_map__set_private(map, priv, bpf_map_priv__clear);
+			if (err) {
+				bpf_map_priv__clear(map, priv);
+				return err;
+			}
+		} else if (evsel) {
+			struct bpf_map_op *op;
+
+			op = bpf_map__add_newop(map, NULL);
+			if (IS_ERR(op))
+				return PTR_ERR(op);
+			op->op_type = BPF_MAP_OP_SET_EVSEL;
+			op->v.evsel = evsel;
 		}
 	}
 
-- 
2.5.5

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

* [PATCH 08/19] perf evsel: Allow specifying a file to output in perf_evsel__print_ip
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (6 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 07/19] perf bpf: Automatically create bpf-output event __bpf_stdout__ Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 09/19] perf evsel: Allow passing a left alignment when printing a symbol Arnaldo Carvalho de Melo
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel, Milian Wolff, Jiri Olsa

From: Milian Wolff <milian.wolff@kdab.com>

As this function will be used in 'perf trace'.

Cc: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/n/tip-8x297v9utnxq77onikevvlse@git.kernel.org
[ Split from a larger patch ]
Signed-off-by: Milian Wolff <milian.wolff@kdab.com>
---
 tools/perf/builtin-script.c |  4 ++--
 tools/perf/util/session.c   | 39 +++++++++++++++++++++------------------
 tools/perf/util/session.h   |  3 ++-
 3 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 8f6ab2ac855a..dbf208f0cdc2 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -580,7 +580,7 @@ static void print_sample_bts(struct perf_sample *sample,
 			}
 		}
 		perf_evsel__print_ip(evsel, sample, al, print_opts,
-				     scripting_max_stack);
+				     scripting_max_stack, stdout);
 	}
 
 	/* print branch_to information */
@@ -790,7 +790,7 @@ static void process_event(struct perf_script *script,
 
 		perf_evsel__print_ip(evsel, sample, al,
 				     output[attr->type].print_ip_opts,
-				     scripting_max_stack);
+				     scripting_max_stack, stdout);
 	}
 
 	if (PRINT_FIELD(IREGS))
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ef370557fb9a..bbac0efbc10c 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1955,7 +1955,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 
 void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 			  struct addr_location *al,
-			  unsigned int print_opts, unsigned int stack_depth)
+			  unsigned int print_opts, unsigned int stack_depth,
+			  FILE *fp)
 {
 	struct callchain_cursor_node *node;
 	int print_ip = print_opts & PRINT_IP_OPT_IP;
@@ -1992,33 +1993,35 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 				goto next;
 
 			if (print_ip)
-				printf("%c%16" PRIx64, s, node->ip);
+				fprintf(fp, "%c%16" PRIx64, s, node->ip);
 
 			if (node->map)
 				addr = node->map->map_ip(node->map, node->ip);
 
 			if (print_sym) {
-				printf(" ");
+				fprintf(fp, " ");
 				if (print_symoffset) {
 					node_al.addr = addr;
 					node_al.map  = node->map;
-					symbol__fprintf_symname_offs(node->sym, &node_al, stdout);
+					symbol__fprintf_symname_offs(node->sym,
+								     &node_al,
+								     fp);
 				} else
-					symbol__fprintf_symname(node->sym, stdout);
+					symbol__fprintf_symname(node->sym, fp);
 			}
 
 			if (print_dso) {
-				printf(" (");
-				map__fprintf_dsoname(node->map, stdout);
-				printf(")");
+				fprintf(fp, " (");
+				map__fprintf_dsoname(node->map, fp);
+				fprintf(fp, ")");
 			}
 
 			if (print_srcline)
 				map__fprintf_srcline(node->map, addr, "\n  ",
-						     stdout);
+						     fp);
 
 			if (!print_oneline)
-				printf("\n");
+				fprintf(fp, "\n");
 
 			stack_depth--;
 next:
@@ -2030,25 +2033,25 @@ next:
 			return;
 
 		if (print_ip)
-			printf("%16" PRIx64, sample->ip);
+			fprintf(fp, "%16" PRIx64, sample->ip);
 
 		if (print_sym) {
-			printf(" ");
+			fprintf(fp, " ");
 			if (print_symoffset)
 				symbol__fprintf_symname_offs(al->sym, al,
-							     stdout);
+							     fp);
 			else
-				symbol__fprintf_symname(al->sym, stdout);
+				symbol__fprintf_symname(al->sym, fp);
 		}
 
 		if (print_dso) {
-			printf(" (");
-			map__fprintf_dsoname(al->map, stdout);
-			printf(")");
+			fprintf(fp, " (");
+			map__fprintf_dsoname(al->map, fp);
+			fprintf(fp, ")");
 		}
 
 		if (print_srcline)
-			map__fprintf_srcline(al->map, al->addr, "\n  ", stdout);
+			map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 	}
 }
 
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index f96fc9e8c52e..0ee3d9dbc099 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -106,7 +106,8 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 
 void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 			  struct addr_location *al,
-			  unsigned int print_opts, unsigned int stack_depth);
+			  unsigned int print_opts, unsigned int stack_depth,
+			  FILE *fp);
 
 int perf_session__cpu_bitmap(struct perf_session *session,
 			     const char *cpu_list, unsigned long *cpu_bitmap);
-- 
2.5.5

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

* [PATCH 09/19] perf evsel: Allow passing a left alignment when printing a symbol
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (7 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 08/19] perf evsel: Allow specifying a file to output in perf_evsel__print_ip Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 10/19] perf trace: Add support for printing call chains on sys_exit events Arnaldo Carvalho de Melo
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

For callchains, etc where we want it to align just below the syscall
name, for instance, in 'perf trace'

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-uk9ekchd67651c625ltaur5y@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-script.c | 4 ++--
 tools/perf/util/session.c   | 6 +++++-
 tools/perf/util/session.h   | 2 +-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index dbf208f0cdc2..60fde9f5025c 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -579,7 +579,7 @@ static void print_sample_bts(struct perf_sample *sample,
 				print_opts &= ~PRINT_IP_OPT_SRCLINE;
 			}
 		}
-		perf_evsel__print_ip(evsel, sample, al, print_opts,
+		perf_evsel__print_ip(evsel, sample, al, 0, print_opts,
 				     scripting_max_stack, stdout);
 	}
 
@@ -788,7 +788,7 @@ static void process_event(struct perf_script *script,
 		else
 			printf("\n");
 
-		perf_evsel__print_ip(evsel, sample, al,
+		perf_evsel__print_ip(evsel, sample, al, 0,
 				     output[attr->type].print_ip_opts,
 				     scripting_max_stack, stdout);
 	}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index bbac0efbc10c..62b6d4051b99 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1954,7 +1954,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 }
 
 void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
-			  struct addr_location *al,
+			  struct addr_location *al, int left_alignment,
 			  unsigned int print_opts, unsigned int stack_depth,
 			  FILE *fp)
 {
@@ -1992,6 +1992,8 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 			if (node->sym && node->sym->ignore)
 				goto next;
 
+			fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
+
 			if (print_ip)
 				fprintf(fp, "%c%16" PRIx64, s, node->ip);
 
@@ -2032,6 +2034,8 @@ next:
 		if (al->sym && al->sym->ignore)
 			return;
 
+		fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
+
 		if (print_ip)
 			fprintf(fp, "%16" PRIx64, sample->ip);
 
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 0ee3d9dbc099..a6bc4ddbae3e 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -105,7 +105,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 					    unsigned int type);
 
 void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
-			  struct addr_location *al,
+			  struct addr_location *al, int left_alignment,
 			  unsigned int print_opts, unsigned int stack_depth,
 			  FILE *fp);
 
-- 
2.5.5

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

* [PATCH 10/19] perf trace: Add support for printing call chains on sys_exit events.
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (8 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 09/19] perf evsel: Allow passing a left alignment when printing a symbol Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 11/19] perf evsel: Rename print_ip() to fprintf_sym() Arnaldo Carvalho de Melo
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Milian Wolff, Adrian Hunter, David Ahern, Jiri Olsa,
	Namhyung Kim, Wang Nan, Arnaldo Carvalho de Melo

From: Milian Wolff <milian.wolff@kdab.com>

Now, one can print the call chain for every encountered sys_exit event,
e.g.:

    $ perf trace -e nanosleep --call-graph dwarf path/to/ex_sleep
    1005.757 (1000.090 ms): ex_sleep/13167 nanosleep(...) = 0
                                             syscall_slow_exit_work ([kernel.kallsyms])
                                             syscall_return_slowpath ([kernel.kallsyms])
                                             int_ret_from_sys_call ([kernel.kallsyms])
                                             __nanosleep (/usr/lib/libc-2.23.so)
                                             [unknown] (/usr/lib/libQt5Core.so.5.6.0)
                                             QThread::sleep (/usr/lib/libQt5Core.so.5.6.0)
                                             main (path/to/ex_sleep)
                                             __libc_start_main (/usr/lib/libc-2.23.so)
                                             _start (path/to/ex_sleep)

Note that it is advised to increase the number of mmap pages to prevent
event losses when using this new feature. Often, adding `-m 10M` to the
`perf trace` invocation is enough.

This feature is also available in strace when built with libunwind via
`strace -k`. Performance wise, this solution is much better:

    $ time find path/to/linux &> /dev/null

    real    0m0.051s
    user    0m0.013s
    sys     0m0.037s

    $ time perf trace -m 800M --call-graph dwarf find path/to/linux &> /dev/null

    real    0m2.624s
    user    0m1.203s
    sys     0m1.333s

    $ time strace -k find path/to/linux  &> /dev/null

    real    0m35.398s
    user    0m10.403s
    sys     0m23.173s

Note that it is currently not possible to configure the print output.
Adding such a feature, similar to what is available in `perf script` via
its `--fields` knob can be added later on.

Signed-off-by: Milian Wolff <milian.wolff@kdab.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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>
LPU-Reference: 1460115255-17648-1-git-send-email-milian.wolff@kdab.com
[ Split from a larger patch, do not print the IP, left align,
  remove dup call symbol__init(), added man page entry ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt |  6 ++++++
 tools/perf/builtin-trace.c              | 22 ++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 13293de8869f..ed485df16409 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -117,6 +117,12 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
 --syscalls::
 	Trace system calls. This options is enabled by default.
 
+--call-graph [mode,type,min[,limit],order[,key][,branch]]::
+        Setup and enable call-graph (stack chain/backtrace) recording.
+        See `--call-graph` section in perf-record and perf-report
+        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'.
+
 --event::
 	Trace other events, see 'perf list' for a complete list.
 
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 27d987030627..8c587a8d3742 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -34,6 +34,7 @@
 #include "trace-event.h"
 #include "util/parse-events.h"
 #include "util/bpf-loader.h"
+#include "callchain.h"
 #include "syscalltbl.h"
 
 #include <libaudit.h> /* FIXME: Still needed for audit_errno_to_name */
@@ -2190,6 +2191,21 @@ signed_print:
 		goto signed_print;
 
 	fputc('\n', trace->output);
+
+	if (sample->callchain) {
+		struct addr_location al;
+		/* TODO: user-configurable print_opts */
+		const unsigned int print_opts = PRINT_IP_OPT_SYM
+					      | PRINT_IP_OPT_DSO;
+
+		if (machine__resolve(trace->host, &al, sample) < 0) {
+			pr_err("problem processing %d event, skipping it.\n",
+			       event->header.type);
+			goto out_put;
+		}
+		perf_evsel__print_ip(evsel, sample, &al, 38, print_opts,
+				     scripting_max_stack, trace->output);
+	}
 out:
 	ttrace->entry_pending = false;
 	err = 0;
@@ -3250,6 +3266,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		     "Trace pagefaults", parse_pagefaults, "maj"),
 	OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
 	OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
+	OPT_CALLBACK(0, "call-graph", &trace.opts,
+		     "record_mode[,record_size]", record_callchain_help,
+		     &record_parse_callchain_opt),
 	OPT_UINTEGER(0, "proc-map-timeout", &trace.opts.proc_map_timeout,
 			"per thread proc mmap processing timeout in ms"),
 	OPT_END()
@@ -3285,6 +3304,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		trace.opts.sample_time = true;
 	}
 
+	if (trace.opts.callgraph_set)
+		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] 21+ messages in thread

* [PATCH 11/19] perf evsel: Rename print_ip() to fprintf_sym()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (9 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 10/19] perf trace: Add support for printing call chains on sys_exit events Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 12/19] perf evsel: Introduce fprintf_callchain() method out of fprintf_sym() Arnaldo Carvalho de Melo
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

As it receives a FILE, and its more than just the IP, which can even be
requested not to be printed.

For consistency with other similar methods in tools/perf/, name it as
perf_evsel__fprintf_sym() and make it return the number of bytes
printed, just like 'fprintf(3)'

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-84gawlqa3lhk63nf0t9vnqnn@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-script.c | 10 ++++----
 tools/perf/builtin-trace.c  |  4 +--
 tools/perf/util/session.c   | 60 +++++++++++++++++++++------------------------
 tools/perf/util/session.h   |  8 +++---
 4 files changed, 39 insertions(+), 43 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 60fde9f5025c..ddd5b79e94c2 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -579,8 +579,8 @@ static void print_sample_bts(struct perf_sample *sample,
 				print_opts &= ~PRINT_IP_OPT_SRCLINE;
 			}
 		}
-		perf_evsel__print_ip(evsel, sample, al, 0, print_opts,
-				     scripting_max_stack, stdout);
+		perf_evsel__fprintf_sym(evsel, sample, al, 0, print_opts,
+					scripting_max_stack, stdout);
 	}
 
 	/* print branch_to information */
@@ -788,9 +788,9 @@ static void process_event(struct perf_script *script,
 		else
 			printf("\n");
 
-		perf_evsel__print_ip(evsel, sample, al, 0,
-				     output[attr->type].print_ip_opts,
-				     scripting_max_stack, stdout);
+		perf_evsel__fprintf_sym(evsel, sample, al, 0,
+					output[attr->type].print_ip_opts,
+					scripting_max_stack, stdout);
 	}
 
 	if (PRINT_FIELD(IREGS))
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 8c587a8d3742..a0d5c680c39e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2203,8 +2203,8 @@ signed_print:
 			       event->header.type);
 			goto out_put;
 		}
-		perf_evsel__print_ip(evsel, sample, &al, 38, print_opts,
-				     scripting_max_stack, trace->output);
+		perf_evsel__fprintf_sym(evsel, sample, &al, 38, print_opts,
+					scripting_max_stack, trace->output);
 	}
 out:
 	ttrace->entry_pending = false;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 62b6d4051b99..0669a088ea0d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1953,11 +1953,12 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 	return NULL;
 }
 
-void perf_evsel__print_ip(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, unsigned int stack_depth,
+			    FILE *fp)
 {
+	int printed = 0;
 	struct callchain_cursor_node *node;
 	int print_ip = print_opts & PRINT_IP_OPT_IP;
 	int print_sym = print_opts & PRINT_IP_OPT_SYM;
@@ -1975,7 +1976,7 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 					      stack_depth) != 0) {
 			if (verbose)
 				error("Failed to resolve callchain. Skipping\n");
-			return;
+			return printed;
 		}
 		callchain_cursor_commit(&callchain_cursor);
 
@@ -1992,71 +1993,66 @@ void perf_evsel__print_ip(struct perf_evsel *evsel, struct perf_sample *sample,
 			if (node->sym && node->sym->ignore)
 				goto next;
 
-			fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
+			printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 
 			if (print_ip)
-				fprintf(fp, "%c%16" PRIx64, s, node->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) {
-				fprintf(fp, " ");
+				printed += fprintf(fp, " ");
 				if (print_symoffset) {
 					node_al.addr = addr;
 					node_al.map  = node->map;
-					symbol__fprintf_symname_offs(node->sym,
-								     &node_al,
-								     fp);
+					printed += symbol__fprintf_symname_offs(node->sym, &node_al, fp);
 				} else
-					symbol__fprintf_symname(node->sym, fp);
+					printed += symbol__fprintf_symname(node->sym, fp);
 			}
 
 			if (print_dso) {
-				fprintf(fp, " (");
-				map__fprintf_dsoname(node->map, fp);
-				fprintf(fp, ")");
+				printed += fprintf(fp, " (");
+				printed += map__fprintf_dsoname(node->map, fp);
+				printed += fprintf(fp, ")");
 			}
 
 			if (print_srcline)
-				map__fprintf_srcline(node->map, addr, "\n  ",
-						     fp);
+				printed += map__fprintf_srcline(node->map, addr, "\n  ", fp);
 
 			if (!print_oneline)
-				fprintf(fp, "\n");
+				printed += fprintf(fp, "\n");
 
 			stack_depth--;
 next:
 			callchain_cursor_advance(&callchain_cursor);
 		}
 
-	} else {
-		if (al->sym && al->sym->ignore)
-			return;
-
-		fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
+	} else if (!(al->sym && al->sym->ignore)) {
+		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 
 		if (print_ip)
-			fprintf(fp, "%16" PRIx64, sample->ip);
+			printed += fprintf(fp, "%16" PRIx64, sample->ip);
 
 		if (print_sym) {
-			fprintf(fp, " ");
+			printed += fprintf(fp, " ");
 			if (print_symoffset)
-				symbol__fprintf_symname_offs(al->sym, al,
-							     fp);
+				printed += symbol__fprintf_symname_offs(al->sym, al, fp);
 			else
-				symbol__fprintf_symname(al->sym, fp);
+				printed += symbol__fprintf_symname(al->sym, fp);
 		}
 
 		if (print_dso) {
-			fprintf(fp, " (");
-			map__fprintf_dsoname(al->map, fp);
-			fprintf(fp, ")");
+			printed += fprintf(fp, " (");
+			printed += map__fprintf_dsoname(al->map, fp);
+			printed += fprintf(fp, ")");
 		}
 
 		if (print_srcline)
-			map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
+			printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 	}
+
+	return printed;
 }
 
 int perf_session__cpu_bitmap(struct perf_session *session,
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index a6bc4ddbae3e..ac834908bb35 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -104,10 +104,10 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp);
 struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 					    unsigned int type);
 
-void perf_evsel__print_ip(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, unsigned int stack_depth,
+			    FILE *fp);
 
 int perf_session__cpu_bitmap(struct perf_session *session,
 			     const char *cpu_list, unsigned long *cpu_bitmap);
-- 
2.5.5

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

* [PATCH 12/19] perf evsel: Introduce fprintf_callchain() method out of fprintf_sym()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (10 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 11/19] perf evsel: Rename print_ip() to fprintf_sym() Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 13/19] perf trace: Exclude the kernel part of the callchain leading to a syscall Arnaldo Carvalho de Melo
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

In 'perf trace' we're just interested in printing callchains, and we
don't want to use the symbol_conf.use_callchain, so move the callchain
part to a new method.

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-kcn3romzivcpxb3u75s9nz33@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c |  4 ++--
 tools/perf/util/evsel.h    |  6 ++++++
 tools/perf/util/session.c  | 29 ++++++++++++++++++++++++-----
 3 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index a0d5c680c39e..63a3cc9b717c 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2203,8 +2203,8 @@ signed_print:
 			       event->header.type);
 			goto out_put;
 		}
-		perf_evsel__fprintf_sym(evsel, sample, &al, 38, print_opts,
-					scripting_max_stack, trace->output);
+		perf_evsel__fprintf_callchain(evsel, sample, &al, 38, print_opts,
+					      scripting_max_stack, trace->output);
 	}
 out:
 	ttrace->entry_pending = false;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 501ea6e565f1..ab3632caba9f 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -381,6 +381,12 @@ struct perf_attr_details {
 int perf_evsel__fprintf(struct perf_evsel *evsel,
 			struct perf_attr_details *details, FILE *fp);
 
+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);
+
 bool perf_evsel__fallback(struct perf_evsel *evsel, int err,
 			  char *msg, size_t msgsize);
 int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 0669a088ea0d..e384b651a3e8 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1953,10 +1953,10 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
 	return NULL;
 }
 
-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)
+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 printed = 0;
 	struct callchain_cursor_node *node;
@@ -1968,7 +1968,7 @@ int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample
 	int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
 	char s = print_oneline ? ' ' : '\t';
 
-	if (symbol_conf.use_callchain && sample->callchain) {
+	if (sample->callchain) {
 		struct addr_location node_al;
 
 		if (thread__resolve_callchain(al->thread, evsel,
@@ -2027,7 +2027,26 @@ int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample
 next:
 			callchain_cursor_advance(&callchain_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, unsigned int stack_depth,
+			    FILE *fp)
+{
+	int printed = 0;
+	int print_ip = print_opts & PRINT_IP_OPT_IP;
+	int print_sym = print_opts & PRINT_IP_OPT_SYM;
+	int print_dso = print_opts & PRINT_IP_OPT_DSO;
+	int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
+	int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
 
+	if (symbol_conf.use_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)) {
 		printed += fprintf(fp, "%-*.*s", left_alignment, left_alignment, " ");
 
-- 
2.5.5

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

* [PATCH 13/19] perf trace: Exclude the kernel part of the callchain leading to a syscall
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (11 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 12/19] perf evsel: Introduce fprintf_callchain() method out of fprintf_sym() Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 14/19] perf evsel: Do not use globals in config() Arnaldo Carvalho de Melo
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The kernel parts are not that useful:

  # trace -m 512 -e nanosleep --call dwarf  usleep 1
     0.065 ( 0.065 ms): usleep/18732 nanosleep(rqtp: 0x7ffc4ee4e200) = 0
                                       syscall_slow_exit_work ([kernel.kallsyms])
                                       do_syscall_64 ([kernel.kallsyms])
                                       return_from_SYSCALL_64 ([kernel.kallsyms])
                                       __nanosleep (/usr/lib64/libc-2.22.so)
                                       usleep (/usr/lib64/libc-2.22.so)
                                       main (/usr/bin/usleep)
                                       __libc_start_main (/usr/lib64/libc-2.22.so)
                                       _start (/usr/bin/usleep)
  #

So lets just use perf_event_attr.exclude_callchain_kernel to avoid
collecting it in the ring buffer:

  # trace -m 512 -e nanosleep --call dwarf  usleep 1
     0.063 ( 0.063 ms): usleep/19212 nanosleep(rqtp: 0x7ffc3df10fb0) = 0
                                       __nanosleep (/usr/lib64/libc-2.22.so)
                                       usleep (/usr/lib64/libc-2.22.so)
                                       main (/usr/bin/usleep)
                                       __libc_start_main (/usr/lib64/libc-2.22.so)
                                       _start (/usr/bin/usleep)
  #

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-qctu3gqhpim0dfbcp9d86c91@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-trace.txt |  3 +++
 tools/perf/builtin-trace.c              | 13 +++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index ed485df16409..1bbcf305d233 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -123,6 +123,9 @@ 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'.
 
+--kernel-syscall-graph::
+	 Show the kernel callchains on the syscall exit path.
+
 --event::
 	Trace other events, see 'perf list' for a complete list.
 
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 63a3cc9b717c..cfa5ce8fdb7b 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -159,6 +159,7 @@ struct trace {
 	bool			show_comm;
 	bool			show_tool_stats;
 	bool			trace_syscalls;
+	bool			kernel_syscallchains;
 	bool			force;
 	bool			vfs_getname;
 	int			trace_pgfaults;
@@ -2661,6 +2662,15 @@ static int trace__add_syscall_newtp(struct trace *trace)
 	perf_evlist__add(evlist, sys_enter);
 	perf_evlist__add(evlist, sys_exit);
 
+	if (trace->opts.callgraph_set && !trace->kernel_syscallchains) {
+		/*
+		 * We're interested only in the user space callchain
+		 * leading to the syscall, allow overriding that for
+		 * debugging reasons using --kernel_syscall_callchains
+		 */
+		sys_exit->attr.exclude_callchain_kernel = 1;
+	}
+
 	trace->syscalls.events.sys_enter = sys_enter;
 	trace->syscalls.events.sys_exit  = sys_exit;
 
@@ -3221,6 +3231,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 		.output = stderr,
 		.show_comm = true,
 		.trace_syscalls = true,
+		.kernel_syscallchains = false,
 	};
 	const char *output_name = NULL;
 	const char *ev_qualifier_str = NULL;
@@ -3269,6 +3280,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_CALLBACK(0, "call-graph", &trace.opts,
 		     "record_mode[,record_size]", record_callchain_help,
 		     &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, "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] 21+ messages in thread

* [PATCH 14/19] perf evsel: Do not use globals in config()
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (12 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 13/19] perf trace: Exclude the kernel part of the callchain leading to a syscall Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 15/19] perf evlist: Add (reset,set)_sample_bit methods Arnaldo Carvalho de Melo
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

Instead receive a callchain_param pointer to configure callchain
aspects, not doing so if NULL is passed.

This will allow fine grained control over which evsels in an evlist
gets callchains enabled.

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-2mupip6khc92mh5x4nw9to82@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/tests/perf-time-to-tsc.c | 2 +-
 tools/perf/builtin-kvm.c                     | 2 +-
 tools/perf/builtin-record.c                  | 2 +-
 tools/perf/builtin-top.c                     | 2 +-
 tools/perf/builtin-trace.c                   | 2 +-
 tools/perf/tests/bpf.c                       | 2 +-
 tools/perf/tests/code-reading.c              | 2 +-
 tools/perf/tests/keep-tracking.c             | 2 +-
 tools/perf/tests/openat-syscall-tp-fields.c  | 2 +-
 tools/perf/tests/perf-record.c               | 2 +-
 tools/perf/tests/switch-tracking.c           | 2 +-
 tools/perf/util/evlist.h                     | 5 ++++-
 tools/perf/util/evsel.c                      | 7 ++++---
 tools/perf/util/evsel.h                      | 5 ++++-
 tools/perf/util/record.c                     | 5 +++--
 15 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/tools/perf/arch/x86/tests/perf-time-to-tsc.c b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
index 9d29ee283ac5..d4aa567a29c4 100644
--- a/tools/perf/arch/x86/tests/perf-time-to-tsc.c
+++ b/tools/perf/arch/x86/tests/perf-time-to-tsc.c
@@ -71,7 +71,7 @@ int test__perf_time_to_tsc(int subtest __maybe_unused)
 
 	CHECK__(parse_events(evlist, "cycles:u", NULL));
 
-	perf_evlist__config(evlist, &opts);
+	perf_evlist__config(evlist, &opts, NULL);
 
 	evsel = perf_evlist__first(evlist);
 
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index bff666458b28..6487c06d2708 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -982,7 +982,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm)
 	struct perf_evlist *evlist = kvm->evlist;
 	char sbuf[STRERR_BUFSIZE];
 
-	perf_evlist__config(evlist, &kvm->opts);
+	perf_evlist__config(evlist, &kvm->opts, NULL);
 
 	/*
 	 * Note: exclude_{guest,host} do not apply here.
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e64bd1ee5acb..eb6a199a833c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -284,7 +284,7 @@ static int record__open(struct record *rec)
 	struct record_opts *opts = &rec->opts;
 	int rc = 0;
 
-	perf_evlist__config(evlist, opts);
+	perf_evlist__config(evlist, opts, &callchain_param);
 
 	evlist__for_each(evlist, pos) {
 try_again:
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 833214979c4f..8846df0ec0c3 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -886,7 +886,7 @@ static int perf_top__start_counters(struct perf_top *top)
 	struct perf_evlist *evlist = top->evlist;
 	struct record_opts *opts = &top->record_opts;
 
-	perf_evlist__config(evlist, opts);
+	perf_evlist__config(evlist, opts, &callchain_param);
 
 	evlist__for_each(evlist, counter) {
 try_again:
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index cfa5ce8fdb7b..08fb100b91fa 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2749,7 +2749,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 		goto out_delete_evlist;
 	}
 
-	perf_evlist__config(evlist, &trace->opts);
+	perf_evlist__config(evlist, &trace->opts, &callchain_param);
 
 	signal(SIGCHLD, sig_handler);
 	signal(SIGINT, sig_handler);
diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c
index 199501c71e27..f31eed31c1a9 100644
--- a/tools/perf/tests/bpf.c
+++ b/tools/perf/tests/bpf.c
@@ -138,7 +138,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void),
 	perf_evlist__splice_list_tail(evlist, &parse_evlist.list);
 	evlist->nr_groups = parse_evlist.nr_groups;
 
-	perf_evlist__config(evlist, &opts);
+	perf_evlist__config(evlist, &opts, NULL);
 
 	err = perf_evlist__open(evlist);
 	if (err < 0) {
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index abd3f0ec0c0b..68a69a195545 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -532,7 +532,7 @@ static int do_test_code_reading(bool try_kcore)
 			goto out_put;
 		}
 
-		perf_evlist__config(evlist, &opts);
+		perf_evlist__config(evlist, &opts, NULL);
 
 		evsel = perf_evlist__first(evlist);
 
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index ddb78fae064a..614e45a3c603 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -80,7 +80,7 @@ int test__keep_tracking(int subtest __maybe_unused)
 	CHECK__(parse_events(evlist, "dummy:u", NULL));
 	CHECK__(parse_events(evlist, "cycles:u", NULL));
 
-	perf_evlist__config(evlist, &opts);
+	perf_evlist__config(evlist, &opts, NULL);
 
 	evsel = perf_evlist__first(evlist);
 
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index eb99a105f31c..4344fe482c1d 100644
--- a/tools/perf/tests/openat-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -44,7 +44,7 @@ int test__syscall_openat_tp_fields(int subtest __maybe_unused)
 		goto out_delete_evlist;
 	}
 
-	perf_evsel__config(evsel, &opts);
+	perf_evsel__config(evsel, &opts, NULL);
 
 	thread_map__set_pid(evlist->threads, 0, getpid());
 
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c
index 1cc78cefe399..b836ee6a8d9b 100644
--- a/tools/perf/tests/perf-record.c
+++ b/tools/perf/tests/perf-record.c
@@ -99,7 +99,7 @@ int test__PERF_RECORD(int subtest __maybe_unused)
 	perf_evsel__set_sample_bit(evsel, CPU);
 	perf_evsel__set_sample_bit(evsel, TID);
 	perf_evsel__set_sample_bit(evsel, TIME);
-	perf_evlist__config(evlist, &opts);
+	perf_evlist__config(evlist, &opts, NULL);
 
 	err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask);
 	if (err < 0) {
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index ebd80168d51e..39a689bf7574 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -417,7 +417,7 @@ int test__switch_tracking(int subtest __maybe_unused)
 	perf_evsel__set_sample_bit(tracking_evsel, TIME);
 
 	/* Config events */
-	perf_evlist__config(evlist, &opts);
+	perf_evlist__config(evlist, &opts, NULL);
 
 	/* Check moved event is still at the front */
 	if (cycles_evsel != perf_evlist__first(evlist)) {
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index a0d15221db6e..8db9228663d6 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -123,11 +123,14 @@ void perf_evlist__mmap_consume(struct perf_evlist *evlist, int idx);
 int perf_evlist__open(struct perf_evlist *evlist);
 void perf_evlist__close(struct perf_evlist *evlist);
 
+struct callchain_param;
+
 void perf_evlist__set_id_pos(struct perf_evlist *evlist);
 bool perf_can_sample_identifier(void);
 bool perf_can_record_switch_events(void);
 bool perf_can_record_cpu_wide(void);
-void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts);
+void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
+			 struct callchain_param *callchain);
 int record_opts__config(struct record_opts *opts);
 
 int perf_evlist__prepare_workload(struct perf_evlist *evlist,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3fd7c2c72f4a..84252729222d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -737,7 +737,8 @@ static void apply_config_terms(struct perf_evsel *evsel,
  *     enable/disable events specifically, as there's no
  *     initial traced exec call.
  */
-void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
+void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
+			struct callchain_param *callchain)
 {
 	struct perf_evsel *leader = evsel->leader;
 	struct perf_event_attr *attr = &evsel->attr;
@@ -812,8 +813,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
 	if (perf_evsel__is_function_event(evsel))
 		evsel->attr.exclude_callchain_user = 1;
 
-	if (callchain_param.enabled && !evsel->no_aux_samples)
-		perf_evsel__config_callgraph(evsel, opts, &callchain_param);
+	if (callchain && callchain->enabled && !evsel->no_aux_samples)
+		perf_evsel__config_callgraph(evsel, opts, callchain);
 
 	if (opts->sample_intr_regs) {
 		attr->sample_regs_intr = opts->sample_intr_regs;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index ab3632caba9f..7e45d2130a0f 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -178,8 +178,11 @@ void perf_evsel__init(struct perf_evsel *evsel,
 void perf_evsel__exit(struct perf_evsel *evsel);
 void perf_evsel__delete(struct perf_evsel *evsel);
 
+struct callchain_param;
+
 void perf_evsel__config(struct perf_evsel *evsel,
-			struct record_opts *opts);
+			struct record_opts *opts,
+			struct callchain_param *callchain);
 
 int __perf_evsel__sample_size(u64 sample_type);
 void perf_evsel__calc_id_pos(struct perf_evsel *evsel);
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 0467367dc315..481792c7484b 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -129,7 +129,8 @@ bool perf_can_record_cpu_wide(void)
 	return true;
 }
 
-void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
+void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts,
+			 struct callchain_param *callchain)
 {
 	struct perf_evsel *evsel;
 	bool use_sample_identifier = false;
@@ -148,7 +149,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
 	use_comm_exec = perf_can_comm_exec();
 
 	evlist__for_each(evlist, evsel) {
-		perf_evsel__config(evsel, opts);
+		perf_evsel__config(evsel, opts, callchain);
 		if (evsel->tracking && use_comm_exec)
 			evsel->attr.comm_exec = 1;
 	}
-- 
2.5.5

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

* [PATCH 15/19] perf evlist: Add (reset,set)_sample_bit methods
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (13 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 14/19] perf evsel: Do not use globals in config() Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 16/19] perf evsel: Rename config_callgraph() to config_callchain() and make it public Arnaldo Carvalho de Melo
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

For fiddling with sample_type fields in all evsels in an evlist.

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-dg6yavctt0hzl2tsgfb43qsr@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evlist.c | 18 ++++++++++++++++++
 tools/perf/util/evlist.h | 11 +++++++++++
 2 files changed, 29 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 86a03836a83f..4c9f510ae18d 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1192,6 +1192,24 @@ void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus,
 	perf_evlist__propagate_maps(evlist);
 }
 
+void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
+				   enum perf_event_sample_format bit)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(evlist, evsel)
+		__perf_evsel__set_sample_bit(evsel, bit);
+}
+
+void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
+				     enum perf_event_sample_format bit)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(evlist, evsel)
+		__perf_evsel__reset_sample_bit(evsel, bit);
+}
+
 int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel)
 {
 	struct perf_evsel *evsel;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 8db9228663d6..da46423998e8 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -87,6 +87,17 @@ int perf_evlist__add_dummy(struct perf_evlist *evlist);
 int perf_evlist__add_newtp(struct perf_evlist *evlist,
 			   const char *sys, const char *name, void *handler);
 
+void __perf_evlist__set_sample_bit(struct perf_evlist *evlist,
+				   enum perf_event_sample_format bit);
+void __perf_evlist__reset_sample_bit(struct perf_evlist *evlist,
+				     enum perf_event_sample_format bit);
+
+#define perf_evlist__set_sample_bit(evlist, bit) \
+	__perf_evlist__set_sample_bit(evlist, PERF_SAMPLE_##bit)
+
+#define perf_evlist__reset_sample_bit(evlist, bit) \
+	__perf_evlist__reset_sample_bit(evlist, PERF_SAMPLE_##bit)
+
 int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter);
 int perf_evlist__set_filter_pid(struct perf_evlist *evlist, pid_t pid);
 int perf_evlist__set_filter_pids(struct perf_evlist *evlist, size_t npids, pid_t *pids);
-- 
2.5.5

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

* [PATCH 16/19] perf evsel: Rename config_callgraph() to config_callchain() and make it public
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (14 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 15/19] perf evlist: Add (reset,set)_sample_bit methods Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 17/19] perf trace: Make "--call-graph" affect just "raw_syscalls:sys_exit" Arnaldo Carvalho de Melo
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The rename is for consistency with the parameter name.

Make it public for fine grained control of which evsels should have
callchains enabled, like, for instance, will be done in the next
changesets in 'perf trace', to enable callchains just on the
"raw_syscalls:sys_exit" tracepoint.

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-og8vup111rn357g4yagus3ao@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/evsel.c | 11 +++++------
 tools/perf/util/evsel.h |  3 +++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 84252729222d..d475a4ec8b57 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -562,10 +562,9 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
 	return ret;
 }
 
-static void
-perf_evsel__config_callgraph(struct perf_evsel *evsel,
-			     struct record_opts *opts,
-			     struct callchain_param *param)
+void perf_evsel__config_callchain(struct perf_evsel *evsel,
+				  struct record_opts *opts,
+				  struct callchain_param *param)
 {
 	bool function = perf_evsel__is_function_event(evsel);
 	struct perf_event_attr *attr = &evsel->attr;
@@ -705,7 +704,7 @@ static void apply_config_terms(struct perf_evsel *evsel,
 
 		/* set perf-event callgraph */
 		if (param.enabled)
-			perf_evsel__config_callgraph(evsel, opts, &param);
+			perf_evsel__config_callchain(evsel, opts, &param);
 	}
 }
 
@@ -814,7 +813,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,
 		evsel->attr.exclude_callchain_user = 1;
 
 	if (callchain && callchain->enabled && !evsel->no_aux_samples)
-		perf_evsel__config_callgraph(evsel, opts, callchain);
+		perf_evsel__config_callchain(evsel, opts, callchain);
 
 	if (opts->sample_intr_regs) {
 		attr->sample_regs_intr = opts->sample_intr_regs;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 7e45d2130a0f..1bd6c2e02dfa 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -183,6 +183,9 @@ struct callchain_param;
 void perf_evsel__config(struct perf_evsel *evsel,
 			struct record_opts *opts,
 			struct callchain_param *callchain);
+void perf_evsel__config_callchain(struct perf_evsel *evsel,
+				  struct record_opts *opts,
+				  struct callchain_param *callchain);
 
 int __perf_evsel__sample_size(u64 sample_type);
 void perf_evsel__calc_id_pos(struct perf_evsel *evsel);
-- 
2.5.5

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

* [PATCH 17/19] perf trace: Make "--call-graph" affect just "raw_syscalls:sys_exit"
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (15 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 16/19] perf evsel: Rename config_callgraph() to config_callchain() and make it public Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 18/19] perf evsel: Allow unresolved symbol names to be printed as addresses Arnaldo Carvalho de Melo
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

We don't need the callchains at the syscall enter tracepoint, just when
finishing it at syscall exit, so reduce the overhead by asking for
callchains just at syscall exit.

Suggested-by: Milian Wolff <milian.wolff@kdab.com>
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-fja1ods5vqpg42mdz09xcz3r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 08fb100b91fa..60ab7ce3bc90 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2749,7 +2749,27 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 		goto out_delete_evlist;
 	}
 
-	perf_evlist__config(evlist, &trace->opts, &callchain_param);
+	perf_evlist__config(evlist, &trace->opts, NULL);
+
+	if (trace->opts.callgraph_set && trace->syscalls.events.sys_exit) {
+		perf_evsel__config_callchain(trace->syscalls.events.sys_exit,
+					     &trace->opts, &callchain_param);
+               /*
+                * Now we have evsels with different sample_ids, use
+                * PERF_SAMPLE_IDENTIFIER to map from sample to evsel
+                * from a fixed position in each ring buffer record.
+                *
+                * As of this the changeset introducing this comment, this
+                * isn't strictly needed, as the fields that can come before
+                * PERF_SAMPLE_ID are all used, but we'll probably disable
+                * some of those for things like copying the payload of
+                * pointer syscall arguments, and for vfs_getname we don't
+                * need PERF_SAMPLE_ADDR and PERF_SAMPLE_IP, so do this
+                * here as a warning we need to use PERF_SAMPLE_IDENTIFIER.
+                */
+		perf_evlist__set_sample_bit(evlist, IDENTIFIER);
+		perf_evlist__reset_sample_bit(evlist, ID);
+	}
 
 	signal(SIGCHLD, sig_handler);
 	signal(SIGINT, sig_handler);
-- 
2.5.5

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

* [PATCH 18/19] perf evsel: Allow unresolved symbol names to be printed as addresses
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (16 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 17/19] perf trace: Make "--call-graph" affect just "raw_syscalls:sys_exit" Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-12  1:53 ` [PATCH 19/19] perf trace: Print unresolved symbol names " Arnaldo Carvalho de Melo
  2016-04-13  7:03 ` [GIT PULL 00/19] perf/core improvements Ingo Molnar
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

The fprintf_sym() and fprintf_callchain() methods now allow users to
change the existing behaviour of showing "[unknown]" as the name of
unresolved symbols to instead show "[0x123456]", i.e. its address.

The current patch doesn't change tools to use this facility, the results
from 'perf trace' and 'perf script' cotinue like:

70.109 ( 0.001 ms): qemu-system-x8/10153 poll(ufds: 0x7f2d93ffe870, nfds: 1) = 0 Timeout
                                   [unknown] (/usr/lib64/libc-2.22.so)
                                   [unknown] (/usr/lib64/libspice-server.so.1.10.0)
                                   [unknown] (/usr/lib64/libspice-server.so.1.10.0)
                                   [unknown] (/usr/lib64/libspice-server.so.1.10.0)
                                   start_thread+0xca (/usr/lib64/libpthread-2.22.so)
                                   __clone+0x6d (/usr/lib64/libc-2.22.so)

The next patch will make 'perf trace' use the new formatting.

Suggested-by: Milian Wolff <milian.wolff@kdab.com>
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-fja1ods5vqpg42mdz09xcz3r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/session.c | 27 ++++++++++++++++++---------
 tools/perf/util/session.h |  1 +
 tools/perf/util/symbol.c  | 25 +++++++++++++++++++++----
 tools/perf/util/symbol.h  |  6 ++++++
 4 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e384b651a3e8..0516d06a2741 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1966,6 +1966,7 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 	int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
 	int print_oneline = print_opts & PRINT_IP_OPT_ONELINE;
 	int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
+	int print_unknown_as_addr = print_opts & PRINT_IP_OPT_UNKNOWN_AS_ADDR;
 	char s = print_oneline ? ' ' : '\t';
 
 	if (sample->callchain) {
@@ -2003,12 +2004,16 @@ int perf_evsel__fprintf_callchain(struct perf_evsel *evsel, struct perf_sample *
 
 			if (print_sym) {
 				printed += fprintf(fp, " ");
+				node_al.addr = addr;
+				node_al.map  = node->map;
+
 				if (print_symoffset) {
-					node_al.addr = addr;
-					node_al.map  = node->map;
-					printed += symbol__fprintf_symname_offs(node->sym, &node_al, fp);
-				} else
-					printed += symbol__fprintf_symname(node->sym, fp);
+					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) {
@@ -2043,6 +2048,7 @@ int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample
 	int print_dso = print_opts & PRINT_IP_OPT_DSO;
 	int print_symoffset = print_opts & PRINT_IP_OPT_SYMOFFSET;
 	int print_srcline = print_opts & PRINT_IP_OPT_SRCLINE;
+	int print_unknown_as_addr = print_opts & PRINT_IP_OPT_UNKNOWN_AS_ADDR;
 
 	if (symbol_conf.use_callchain && sample->callchain) {
 		printed += perf_evsel__fprintf_callchain(evsel, sample, al, left_alignment,
@@ -2055,10 +2061,13 @@ int perf_evsel__fprintf_sym(struct perf_evsel *evsel, struct perf_sample *sample
 
 		if (print_sym) {
 			printed += fprintf(fp, " ");
-			if (print_symoffset)
-				printed += symbol__fprintf_symname_offs(al->sym, al, fp);
-			else
-				printed += symbol__fprintf_symname(al->sym, 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) {
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index ac834908bb35..4257fac56618 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -42,6 +42,7 @@ struct perf_session {
 #define PRINT_IP_OPT_SYMOFFSET	(1<<3)
 #define PRINT_IP_OPT_ONELINE	(1<<4)
 #define PRINT_IP_OPT_SRCLINE	(1<<5)
+#define PRINT_IP_OPT_UNKNOWN_AS_ADDR (1<<6)
 
 struct perf_tool;
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e7588dc91518..bb162ee433c6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -264,8 +264,9 @@ size_t symbol__fprintf(struct symbol *sym, FILE *fp)
 		       sym->name);
 }
 
-size_t symbol__fprintf_symname_offs(const struct symbol *sym,
-				    const struct addr_location *al, FILE *fp)
+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;
@@ -280,13 +281,29 @@ size_t symbol__fprintf_symname_offs(const struct symbol *sym,
 			length += fprintf(fp, "+0x%lx", offset);
 		}
 		return length;
-	} else
+	} 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, fp);
+	return __symbol__fprintf_symname_offs(sym, NULL, false, fp);
 }
 
 void symbols__delete(struct rb_root *symbols)
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index c8b7544d9267..e2562568418d 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -262,8 +262,14 @@ int symbol__init(struct perf_env *env);
 void symbol__exit(void);
 void symbol__elf_init(void);
 struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name);
+size_t __symbol__fprintf_symname_offs(const struct symbol *sym,
+				      const struct addr_location *al,
+				      bool unknown_as_addr, FILE *fp);
 size_t symbol__fprintf_symname_offs(const struct symbol *sym,
 				    const struct addr_location *al, FILE *fp);
+size_t __symbol__fprintf_symname(const struct symbol *sym,
+				 const struct addr_location *al,
+				 bool unknown_as_addr, FILE *fp);
 size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
 size_t symbol__fprintf(struct symbol *sym, FILE *fp);
 bool symbol_type__is_a(char symbol_type, enum map_type map_type);
-- 
2.5.5

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

* [PATCH 19/19] perf trace: Print unresolved symbol names as addresses
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (17 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 18/19] perf evsel: Allow unresolved symbol names to be printed as addresses Arnaldo Carvalho de Melo
@ 2016-04-12  1:53 ` Arnaldo Carvalho de Melo
  2016-04-13  7:03 ` [GIT PULL 00/19] perf/core improvements Ingo Molnar
  19 siblings, 0 replies; 21+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-04-12  1:53 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>

Instead of having "[unknown]" as the name used for unresolved symbols,
use the address in the callchain, in hexadecimal form:

  28.801 ( 0.007 ms): qemu-system-x8/10065 ppoll(ufds: 0x55c98b39e400, nfds: 72, tsp: 0x7fffe4e4fe60, sigsetsize: 8) = 0 Timeout
                                     ppoll+0x91 (/usr/lib64/libc-2.22.so)
                                     [0x337309] (/usr/bin/qemu-system-x86_64)
                                     [0x336ab4] (/usr/bin/qemu-system-x86_64)
                                     main+0x1724 (/usr/bin/qemu-system-x86_64)
                                     __libc_start_main+0xf0 (/usr/lib64/libc-2.22.so)
                                     [0xc59a9] (/usr/bin/qemu-system-x86_64)
  35.265 (14.805 ms): gnome-shell/2287  ... [continued]: poll()) = 1
                                     [0xf6fdd] (/usr/lib64/libc-2.22.so)
                                     g_main_context_iterate.isra.29+0x17c (/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)

Suggested-by: Milian Wolff <milian.wolff@kdab.com>
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-fja1ods5vqpg42mdz09xcz3r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-trace.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 60ab7ce3bc90..2ec53edcf649 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2196,8 +2196,9 @@ signed_print:
 	if (sample->callchain) {
 		struct addr_location al;
 		/* TODO: user-configurable print_opts */
-		const unsigned int print_opts = PRINT_IP_OPT_SYM
-					      | PRINT_IP_OPT_DSO;
+		const unsigned int print_opts = PRINT_IP_OPT_SYM |
+					        PRINT_IP_OPT_DSO |
+					        PRINT_IP_OPT_UNKNOWN_AS_ADDR;
 
 		if (machine__resolve(trace->host, &al, sample) < 0) {
 			pr_err("problem processing %d event, skipping it.\n",
-- 
2.5.5

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

* Re: [GIT PULL 00/19] perf/core improvements
  2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
                   ` (18 preceding siblings ...)
  2016-04-12  1:53 ` [PATCH 19/19] perf trace: Print unresolved symbol names " Arnaldo Carvalho de Melo
@ 2016-04-13  7:03 ` Ingo Molnar
  19 siblings, 0 replies; 21+ messages in thread
From: Ingo Molnar @ 2016-04-13  7:03 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Adrian Hunter, David Ahern, Jiri Olsa, Milian Wolff,
	Namhyung Kim, pi3orama, Wang Nan, Zefan Li,
	Arnaldo Carvalho de Melo


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

> Hi Ingo,
> 
> 	Please consider pulling, tested with 'perf test', 'make -C tools/perf
> build-test' and building on these userspaces, using docker:
> 
>   # dm
>   alldeps-fedora-rawhide-minus-python-dev: Ok
>   alldeps-fedora-20: Ok
>   alldeps-ubuntu-12.04: Ok
>   minimal-debian-experimental-x-mips64: Ok
>   minimal-debian-experimental-x-mips64el: Ok
>   minimal-debian-experimental-x-mipsel: Ok
>   minimal-ubuntu-x-arm: Ok
>   minimal-ubuntu-x-arm64: Ok
>   minimal-ubuntu-x-ppc64: Ok
>   minimal-ubuntu-x-ppc64el: Ok
>   alldeps-debian: Ok
>   alldeps-mageia: Ok
>   alldeps-rhel7: Ok
>   alldeps-centos: Ok
>   alldeps-opensuse: Ok
>   alldeps-ubuntu: Ok
>   #
> 
> 	This is on top of my previous pull request, that is not yet
> merged: perf-core-for-mingo-20160408.
> 
> Best regards,
> 
> - Arnaldo
> 
> The following changes since commit 99e87f7bb7268cf644add87130590966fd5d0d17:
> 
>   perf symbols: Adjust symbol for shared objects (2016-04-08 09:58:15 -0300)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo-20160411
> 
> for you to fetch changes up to 00768a2bd3245eace0690fcf2c02776a256b66d7:
> 
>   perf trace: Print unresolved symbol names as addresses (2016-04-11 22:18:25 -0300)
> 
> ----------------------------------------------------------------
> perf/core improvements:
> 
> - Automagically create a 'bpf-output' event, easing the setup of BPF
>   C "scripts" that produce output via the perf ring buffer. Now it is
>   just a matter of calling any perf tool, such as 'trace', with a C
>   source file that references the __bpf_stdout__ output channel and
>   that channel will be created and connected to the script:
> 
>   # trace -e nanosleep --event test_bpf_stdout.c usleep 1
>     0.013 ( 0.013 ms): usleep/2818 nanosleep(rqtp: 0x7ffcead45f40                                        ) ...
>     0.013 (         ): __bpf_stdout__:Raise a BPF event!..)
>     0.015 (         ): perf_bpf_probe:func_begin:(ffffffff81112460))
>     0.261 (         ): __bpf_stdout__:Raise a BPF event!..)
>     0.262 (         ): perf_bpf_probe:func_end:(ffffffff81112460 <- ffffffff81003d92))
>     0.264 ( 0.264 ms): usleep/2818  ... [continued]: nanosleep()) = 0
>   #
> 
>   Further work is needed to reduce the number of lines in a perf bpf C source
>   file, this being the part where we greatly reduce the command line setup (Wang Nan)
> 
> - 'perf trace' now supports callchains, with 'trace --call-graph dwarf' using
>   libunwind, just like 'perf top', to ask the kernel for stack dumps for CFI
>   processing. This reduces the overhead by asking just for userspace callchains
>   and also only for the syscall exit tracepoint (raw_syscalls:sys_exit)
>   (Milian Wolff, Arnaldo Carvalho de Melo)
> 
>   Try it with, for instance:
> 
>      # perf trace --call dwarf ping 127.0.0.1
> 
>   An excerpt of a system wide 'perf trace --call dwarf" session is at:
> 
>    https://fedorapeople.org/~acme/perf/perf-trace--call-graph-dwarf--all-cpus.txt
> 
>   You may need to bump the number of mmap pages, using -m/--mmap-pages,
>   but on a Broadwell machine the defaults allowed system wide tracing to
>   work without losing that many records, experiment with just some
>   syscalls, like:
> 
>     # perf trace --call dwarf -e nanosleep,futex
> 
>   All the targets available for 'perf record', 'perf top' (--pid, --tid, --cpu,
>   etc) should work. Also --duration may be interesting to try.
> 
>   To get filenames from in various syscalls pointer args (open, ettc), add this
>   to the mix:
> 
>   # perf probe 'vfs_getname=getname_flags:72 pathname=filename:string'
> 
>   Making this work is next in line:
> 
>      # trace --call dwarf --ev sched:sched_switch/call-graph=fp/ usleep 1
> 
>   I.e. honouring per-tracepoint callchains in 'perf trace' in addition to
>   in raw_syscalls:sys_exit.
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> ----------------------------------------------------------------
> Arnaldo Carvalho de Melo (15):
>       perf script: Use readdir() instead of deprecated readdir_r()
>       perf thread_map: Use readdir() instead of deprecated readdir_r()
>       perf tools: Use readdir() instead of deprecated readdir_r()
>       perf tools: Use readdir() instead of deprecated readdir_r()
>       perf dwarf: Guard !x86_64 definitions under #ifdef else clause
>       perf evsel: Allow passing a left alignment when printing a symbol
>       perf evsel: Rename print_ip() to fprintf_sym()
>       perf evsel: Introduce fprintf_callchain() method out of fprintf_sym()
>       perf trace: Exclude the kernel part of the callchain leading to a syscall
>       perf evsel: Do not use globals in config()
>       perf evlist: Add (reset,set)_sample_bit methods
>       perf evsel: Rename config_callgraph() to config_callchain() and make it public
>       perf trace: Make "--call-graph" affect just "raw_syscalls:sys_exit"
>       perf evsel: Allow unresolved symbol names to be printed as addresses
>       perf trace: Print unresolved symbol names as addresses
> 
> Milian Wolff (2):
>       perf evsel: Allow specifying a file to output in perf_evsel__print_ip
>       perf trace: Add support for printing call chains on sys_exit events.
> 
> Wang Nan (2):
>       perf bpf: Clone bpf stdout events in multiple bpf scripts
>       perf bpf: Automatically create bpf-output event __bpf_stdout__
> 
>  tools/perf/Documentation/perf-trace.txt      |   9 ++
>  tools/perf/arch/x86/tests/perf-time-to-tsc.c |   2 +-
>  tools/perf/arch/x86/util/dwarf-regs.c        |   8 +-
>  tools/perf/builtin-kvm.c                     |   2 +-
>  tools/perf/builtin-record.c                  |  10 +-
>  tools/perf/builtin-script.c                  |  78 +++++++--------
>  tools/perf/builtin-top.c                     |   2 +-
>  tools/perf/builtin-trace.c                   |  65 +++++++++++-
>  tools/perf/tests/bpf.c                       |   2 +-
>  tools/perf/tests/code-reading.c              |   2 +-
>  tools/perf/tests/keep-tracking.c             |   2 +-
>  tools/perf/tests/openat-syscall-tp-fields.c  |   2 +-
>  tools/perf/tests/perf-record.c               |   2 +-
>  tools/perf/tests/switch-tracking.c           |   2 +-
>  tools/perf/util/bpf-loader.c                 | 143 +++++++++++++++++++++++++++
>  tools/perf/util/bpf-loader.h                 |  19 ++++
>  tools/perf/util/event.c                      |  12 +--
>  tools/perf/util/evlist.c                     |  18 ++++
>  tools/perf/util/evlist.h                     |  16 ++-
>  tools/perf/util/evsel.c                      |  16 +--
>  tools/perf/util/evsel.h                      |  14 ++-
>  tools/perf/util/parse-events.c               |  60 +++++------
>  tools/perf/util/record.c                     |   5 +-
>  tools/perf/util/session.c                    |  95 ++++++++++++------
>  tools/perf/util/session.h                    |   8 +-
>  tools/perf/util/symbol.c                     |  25 ++++-
>  tools/perf/util/symbol.h                     |   6 ++
>  tools/perf/util/thread_map.c                 |   8 +-
>  28 files changed, 487 insertions(+), 146 deletions(-)

Pulled, thanks a lot Arnaldo!

	Ingo

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

end of thread, other threads:[~2016-04-13  7:03 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-12  1:53 [GIT PULL 00/19] perf/core improvements Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 01/19] perf script: Use readdir() instead of deprecated readdir_r() Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 02/19] perf thread_map: " Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 03/19] perf tools: " Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 04/19] " Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 05/19] perf dwarf: Guard !x86_64 definitions under #ifdef else clause Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 06/19] perf bpf: Clone bpf stdout events in multiple bpf scripts Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 07/19] perf bpf: Automatically create bpf-output event __bpf_stdout__ Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 08/19] perf evsel: Allow specifying a file to output in perf_evsel__print_ip Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 09/19] perf evsel: Allow passing a left alignment when printing a symbol Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 10/19] perf trace: Add support for printing call chains on sys_exit events Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 11/19] perf evsel: Rename print_ip() to fprintf_sym() Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 12/19] perf evsel: Introduce fprintf_callchain() method out of fprintf_sym() Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 13/19] perf trace: Exclude the kernel part of the callchain leading to a syscall Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 14/19] perf evsel: Do not use globals in config() Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 15/19] perf evlist: Add (reset,set)_sample_bit methods Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 16/19] perf evsel: Rename config_callgraph() to config_callchain() and make it public Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 17/19] perf trace: Make "--call-graph" affect just "raw_syscalls:sys_exit" Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 18/19] perf evsel: Allow unresolved symbol names to be printed as addresses Arnaldo Carvalho de Melo
2016-04-12  1:53 ` [PATCH 19/19] perf trace: Print unresolved symbol names " Arnaldo Carvalho de Melo
2016-04-13  7:03 ` [GIT PULL 00/19] perf/core improvements Ingo Molnar

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.