All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
@ 2010-12-09 20:27 David Ahern
  2010-12-14 12:24 ` Arnaldo Carvalho de Melo
  2010-12-22 11:29 ` [tip:perf/core] perf symbols: " tip-bot for David Ahern
  0 siblings, 2 replies; 9+ messages in thread
From: David Ahern @ 2010-12-09 20:27 UTC (permalink / raw)
  To: linux-perf-users, linux-kernel; +Cc: David Ahern

The symfs argument allows analysis of perf.data file using a locally
accessible filesystem tree with debug symbols - e.g., tree created
during image builds, sshfs mount, loop mounted KVM disk images,
USB keys, initrds, etc. Anything with an OS tree can be analyzed from
anywhere without the need to populate a local data store with
build-ids.

Signed-off-by: David Ahern <daahern@cisco.com>

v2 --> v3: handle symfs="/"

v1 --> v2: removed symfs changes from builtin-annotate.c
           fixed tab/space inconsistencies
           changed new strlen() to symbol_conf.symfs[0]
           added symfs option to Documentation files

---
 tools/perf/Documentation/perf-diff.txt      |    2 +
 tools/perf/Documentation/perf-report.txt    |    3 +
 tools/perf/Documentation/perf-timechart.txt |    2 +
 tools/perf/builtin-diff.c                   |    2 +
 tools/perf/builtin-report.c                 |    2 +
 tools/perf/builtin-timechart.c              |    2 +
 tools/perf/util/hist.c                      |   14 +++++-
 tools/perf/util/symbol.c                    |   57 ++++++++++++++++++++-------
 tools/perf/util/symbol.h                    |    1 +
 9 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 6a9ec2b..74d7481 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -66,6 +66,8 @@ OPTIONS
 --force::
        Don't complain, do it.
 
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
 
 SEE ALSO
 --------
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 59a1f57..9ed6079 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -113,6 +113,9 @@ OPTIONS
 --force::
         Don't complain, do it.
 
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1]
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
index 4b17883..d7b79e2 100644
--- a/tools/perf/Documentation/perf-timechart.txt
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -38,6 +38,8 @@ OPTIONS
 --process::
         Select the processes to display, by name or PID
 
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
 
 SEE ALSO
 --------
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 5e1a043..71126a6 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -192,6 +192,8 @@ static const struct option options[] = {
 	OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
 		   "separator for columns, no spaces will be added between "
 		   "columns '.' is reserved."),
+	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+		    "Look for files with symbols relative to this directory"),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 904519f..57b0f49 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -479,6 +479,8 @@ static const struct option options[] = {
 		   "columns '.' is reserved."),
 	OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
 		    "Only display entries resolved to a symbol"),
+	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+		    "Look for files with symbols relative to this directory"),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index d2fc461..965aa4e 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1021,6 +1021,8 @@ static const struct option options[] = {
 	OPT_CALLBACK('p', "process", NULL, "process",
 		      "process selector. Pass a pid or process name.",
 		       parse_process),
+	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+		    "Look for files with symbols relative to this directory"),
 	OPT_END()
 };
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 2022e87..b6f9f3b 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1092,6 +1092,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 	FILE *file;
 	int err = 0;
 	u64 len;
+	char symfs_filename[PATH_MAX];
+
+	if (filename) {
+		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
+			 symbol_conf.symfs, filename);
+	}
 
 	if (filename == NULL) {
 		if (dso->has_build_id) {
@@ -1100,9 +1106,9 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 			return -ENOMEM;
 		}
 		goto fallback;
-	} else if (readlink(filename, command, sizeof(command)) < 0 ||
+	} else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
 		   strstr(command, "[kernel.kallsyms]") ||
-		   access(filename, R_OK)) {
+		   access(symfs_filename, R_OK)) {
 		free(filename);
 fallback:
 		/*
@@ -1111,6 +1117,8 @@ fallback:
 		 * DSO is the same as when 'perf record' ran.
 		 */
 		filename = dso->long_name;
+		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
+			 symbol_conf.symfs, filename);
 		free_filename = false;
 	}
 
@@ -1137,7 +1145,7 @@ fallback:
 		 "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
 		 map__rip_2objdump(map, sym->start),
 		 map__rip_2objdump(map, sym->end),
-		 filename, filename);
+		 symfs_filename, filename);
 
 	pr_debug("Executing: %s\n", command);
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index a348906..f61b419 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -41,6 +41,7 @@ struct symbol_conf symbol_conf = {
 	.exclude_other	  = true,
 	.use_modules	  = true,
 	.try_vmlinux_path = true,
+	.symfs            = "",
 };
 
 int dso__name_len(const struct dso *self)
@@ -833,8 +834,11 @@ static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
 	char sympltname[1024];
 	Elf *elf;
 	int nr = 0, symidx, fd, err = 0;
+	char name[PATH_MAX];
 
-	fd = open(self->long_name, O_RDONLY);
+	snprintf(name, sizeof(name), "%s%s",
+		 symbol_conf.symfs, self->long_name);
+	fd = open(name, O_RDONLY);
 	if (fd < 0)
 		goto out;
 
@@ -1446,16 +1450,19 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 	     self->origin++) {
 		switch (self->origin) {
 		case DSO__ORIG_BUILD_ID_CACHE:
-			if (dso__build_id_filename(self, name, size) == NULL)
+			/* skip the locally configured cache if a symfs is given */
+			if (symbol_conf.symfs[0] ||
+			    (dso__build_id_filename(self, name, size) == NULL)) {
 				continue;
+			}
 			break;
 		case DSO__ORIG_FEDORA:
-			snprintf(name, size, "/usr/lib/debug%s.debug",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s.debug",
+				 symbol_conf.symfs, self->long_name);
 			break;
 		case DSO__ORIG_UBUNTU:
-			snprintf(name, size, "/usr/lib/debug%s",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s",
+				 symbol_conf.symfs, self->long_name);
 			break;
 		case DSO__ORIG_BUILDID: {
 			char build_id_hex[BUILD_ID_SIZE * 2 + 1];
@@ -1467,12 +1474,13 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 					  sizeof(self->build_id),
 					  build_id_hex);
 			snprintf(name, size,
-				 "/usr/lib/debug/.build-id/%.2s/%s.debug",
-				 build_id_hex, build_id_hex + 2);
+				 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+				 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
 			}
 			break;
 		case DSO__ORIG_DSO:
-			snprintf(name, size, "%s", self->long_name);
+			snprintf(name, size, "%s%s",
+			     symbol_conf.symfs, self->long_name);
 			break;
 		case DSO__ORIG_GUEST_KMODULE:
 			if (map->groups && map->groups->machine)
@@ -1778,17 +1786,20 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
 			     const char *vmlinux, symbol_filter_t filter)
 {
 	int err = -1, fd;
+	char symfs_vmlinux[PATH_MAX];
 
-	fd = open(vmlinux, O_RDONLY);
+	snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s/%s",
+		 symbol_conf.symfs, vmlinux);
+	fd = open(symfs_vmlinux, O_RDONLY);
 	if (fd < 0)
 		return -1;
 
 	dso__set_loaded(self, map->type);
-	err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
+	err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0);
 	close(fd);
 
 	if (err > 0)
-		pr_debug("Using %s for symbols\n", vmlinux);
+		pr_debug("Using %s for symbols\n", symfs_vmlinux);
 
 	return err;
 }
@@ -1861,6 +1872,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
 			goto out_fixup;
 	}
 
+	/* do not try local files if a symfs was given */
+	if (symbol_conf.symfs[0] != 0)
+		return -1;
+
 	/*
 	 * Say the kernel DSO was created when processing the build-id header table,
 	 * we have a build-id, so check if it is the same as the running kernel,
@@ -2210,9 +2225,6 @@ static int vmlinux_path__init(void)
 	struct utsname uts;
 	char bf[PATH_MAX];
 
-	if (uname(&uts) < 0)
-		return -1;
-
 	vmlinux_path = malloc(sizeof(char *) * 5);
 	if (vmlinux_path == NULL)
 		return -1;
@@ -2225,6 +2237,14 @@ static int vmlinux_path__init(void)
 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
 		goto out_fail;
 	++vmlinux_path__nr_entries;
+
+	/* only try running kernel version if no symfs was given */
+	if (symbol_conf.symfs[0] != 0)
+		return 0;
+
+	if (uname(&uts) < 0)
+		return -1;
+
 	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
@@ -2312,6 +2332,13 @@ int symbol__init(void)
 		       symbol_conf.sym_list_str, "symbol") < 0)
 		goto out_free_comm_list;
 
+	/* a path to symbols of "/" is identical to "" 
+	 * reset here for simplicity.
+	 */
+	if ((symbol_conf.symfs[0] == '/') &&
+	    (symbol_conf.symfs[1] == '\0'))
+		symbol_conf.symfs = "";
+
 	symbol_conf.initialized = true;
 	return 0;
 
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 038f220..bbe90d1 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -85,6 +85,7 @@ struct symbol_conf {
        struct strlist	*dso_list,
 			*comm_list,
 			*sym_list;
+	const char	*symfs;
 };
 
 extern struct symbol_conf symbol_conf;
-- 
1.7.2.3


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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-09 20:27 [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree David Ahern
@ 2010-12-14 12:24 ` Arnaldo Carvalho de Melo
  2010-12-14 12:52   ` Arnaldo Carvalho de Melo
  2010-12-22 11:29 ` [tip:perf/core] perf symbols: " tip-bot for David Ahern
  1 sibling, 1 reply; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-12-14 12:24 UTC (permalink / raw)
  To: David Ahern; +Cc: linux-perf-users, linux-kernel

Em Thu, Dec 09, 2010 at 01:27:07PM -0700, David Ahern escreveu:
> The symfs argument allows analysis of perf.data file using a locally
> accessible filesystem tree with debug symbols - e.g., tree created
> during image builds, sshfs mount, loop mounted KVM disk images,
> USB keys, initrds, etc. Anything with an OS tree can be analyzed from
> anywhere without the need to populate a local data store with
> build-ids.
> 
> Signed-off-by: David Ahern <daahern@cisco.com>
> 
> v2 --> v3: handle symfs="/"

> @@ -2312,6 +2332,13 @@ int symbol__init(void)
>  		       symbol_conf.sym_list_str, "symbol") < 0)
>  		goto out_free_comm_list;
>  
> +	/* a path to symbols of "/" is identical to "" 
> +	 * reset here for simplicity.
> +	 */
> +	if ((symbol_conf.symfs[0] == '/') &&
> +	    (symbol_conf.symfs[1] == '\0'))
> +		symbol_conf.symfs = "";
> +
>  	symbol_conf.initialized = true;
>  	return 0;
>  

Call me a nitpicker:

[acme@felicio ~]$ cat realpath.c 
#include <limits.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	char *resolved = realpath(argv[1], NULL);

	puts(resolved);
}
[acme@felicio ~]$ make realpath
cc     realpath.c   -o realpath
[acme@felicio ~]$ ./realpath //
/
[acme@felicio ~]$ ./realpath ////////////////
/
[acme@felicio ~]$ ./realpath /./././
/
[acme@felicio ~]$ ./realpath /..//.
/
[acme@felicio ~]$

I'll fix this up and merge, thanks!

- Arnaldo

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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-14 12:24 ` Arnaldo Carvalho de Melo
@ 2010-12-14 12:52   ` Arnaldo Carvalho de Melo
  2010-12-14 14:06     ` Arnaldo Carvalho de Melo
  2010-12-14 14:27     ` David S. Ahern
  0 siblings, 2 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-12-14 12:52 UTC (permalink / raw)
  To: David Ahern; +Cc: linux-perf-users, linux-kernel

Em Tue, Dec 14, 2010 at 10:24:28AM -0200, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Dec 09, 2010 at 01:27:07PM -0700, David Ahern escreveu:
> > The symfs argument allows analysis of perf.data file using a locally
> > accessible filesystem tree with debug symbols - e.g., tree created
> > during image builds, sshfs mount, loop mounted KVM disk images,
> > USB keys, initrds, etc. Anything with an OS tree can be analyzed from
> > anywhere without the need to populate a local data store with
> > build-ids.
> > 
> > Signed-off-by: David Ahern <daahern@cisco.com>
> > 
> > v2 --> v3: handle symfs="/"
> 
> [acme@felicio ~]$ ./realpath /..//.
> /
> [acme@felicio ~]$
> 
> I'll fix this up and merge, thanks!

Ok, there are still some problems:

It is escaping the symfs jail for /home/acme/bin/perf, /lib64/libpthread-2.5.so
and kernel modules, investigating...

- Arnaldo

[acme@mica linux]$ find /tmp/bla
/tmp/bla
/tmp/bla/lib64
/tmp/bla/lib64/libc-2.5.so
[acme@mica linux]$ perf report -v -g none --stdio --symfs /tmp/bla > /tmp/out
Looking at the vmlinux_path (3 entries long)
Failed to open [kernel.kallsyms], continuing without symbols
dso__synthesize_plt_symbols: problems reading /home/acme/bin/perf PLT info.
dso__synthesize_plt_symbols: problems reading /lib64/libpthread-2.5.so PLT info.
dso__synthesize_plt_symbols: problems reading /lib/modules/2.6.37-rc3-00084-gd937616/kernel/drivers/net/ixgbe/ixgbe.ko PLT info.
[acme@mica linux]$ cat /tmp/out
# Events: 503  cycles
#
# Overhead      Command                                                             Shared Object                         Symbol
# ........  ...........  ........................................................................  .............................
#
    86.67%         perf  [kernel.kallsyms]                                                         0xffffffff8106f697 ! [k] 0xffffffff8106f697
     2.56%      swapper  [kernel.kallsyms]                                                         0xffffffff81089f50 ! [k] 0xffffffff81089f50
     0.84%         perf  /lib64/libc-2.5.so                                                        0x798ed          d [.] __memchr
     0.84%         perf  /home/acme/bin/perf                                                       0x26bf1          G [.] die_builtin
     0.82%         perf  /lib64/libc-2.5.so                                                        0x728ea          d [.] _int_malloc
     0.63%         perf  /lib64/libc-2.5.so                                                        0xe6077          d [.] ___snprintf_chk
     0.63%         perf  /lib64/libc-2.5.so                                                        0x7b528          d [.] __GI_memcpy
     0.63%         perf  /lib64/libc-2.5.so                                                        0x786c0          d [.] index
     0.51%         perf  /lib64/libc-2.5.so                                                        0x625b0          d [.] _IO_getline_internal
     0.42%         perf  /lib64/libc-2.5.so                                                        0x6265a          d [.] _IO_getline_info
     0.42%         perf  /lib64/libc-2.5.so                                                        0x6cbc4          d [.] _IO_new_file_underflow
     0.42%         perf  /lib64/libc-2.5.so                                                        0x6d148          d [.] _IO_un_link_internal
     0.34%         perf  /lib64/libc-2.5.so                                                        0x60c49          d [.] _IO_new_fclose
     0.21%         perf  /lib64/libc-2.5.so                                                        0x5ff40          d [.] __find_specmb
     0.21%         perf  /lib64/libc-2.5.so                                                        0x6c35b          d [.] _IO_new_file_fopen
     0.21%         perf  /home/acme/bin/perf                                                       0x1db4b          G [.] event__synthesize_kernel_mmap
     0.21%         perf  /lib64/libc-2.5.so                                                        0x6d3c5          d [.] _IO_link_in_internal
     0.21%         perf  /lib64/libc-2.5.so                                                        0x34524          d [.] __GI_____strtoll_l_internal
     0.21%         perf  /home/acme/bin/perf                                                       0x4700           G [.] _init
     0.21%         perf  /lib64/libc-2.5.so                                                        0x41907          d [.] _itoa_word
     0.21%         perf  /lib64/libc-2.5.so                                                        0x6148f          d [.] fgets
     0.21%         perf  /home/acme/bin/perf                                                       0x1deca          G [.] event__synthesize_comm
     0.21%         perf  /lib64/libc-2.5.so                                                        0xcfe7d          d [.] __munmap
     0.21%         perf  /lib64/libc-2.5.so                                                        0x79513          d [.] __GI_strstr
     0.21%         perf  /lib64/libc-2.5.so                                                        0x6e060          d [.] _IO_setb_internal
     0.21%         perf  /lib64/libc-2.5.so                                                        0x6bac3          d [.] _IO_file_close_internal
     0.21%         perf  /lib64/libc-2.5.so                                                        0x95dc3          d [.] __getdents64
     0.21%         perf  /lib64/libc-2.5.so                                                        0x6f1b2          d [.] _IO_str_init_static_internal
     0.21%         perf  /lib64/libpthread-2.5.so                                                  0xd210           G [.] __write_nocancel
     0.21%         perf  /lib64/libc-2.5.so                                                        0x9595a          d [.] __readdir_r
     0.21%         perf  /home/acme/bin/perf                                                       0xddbd           G [.] atexit_header
     0.21%         perf  /lib64/libc-2.5.so                                                        0xc4de7          d [.] __GI___open
     0.12%        pcscd  [unknown]                                                                 0x3f44a79110     ! [.] 0x3f44a79110    
     0.09%        pcscd  [kernel.kallsyms]                                                         0xffffffff810e59ac ! [k] 0xffffffff810e59ac
     0.03%         sshd  [kernel.kallsyms]                                                         0xffffffff810f45f9 ! [k] 0xffffffff810f45f9
     0.03%  kworker/0:1  /lib/modules/2.6.37-rc3-00084-gd937616/kernel/drivers/net/ixgbe/ixgbe.ko  0x605            G [k] ixgbe_update_stats
     0.02%         sshd  [unknown]                                                                 0x7f78ed5f8ccb   ! [.] 0x7f78ed5f8ccb  


#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@mica linux]$ 


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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-14 12:52   ` Arnaldo Carvalho de Melo
@ 2010-12-14 14:06     ` Arnaldo Carvalho de Melo
  2010-12-14 14:33       ` David S. Ahern
  2010-12-14 14:27     ` David S. Ahern
  1 sibling, 1 reply; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-12-14 14:06 UTC (permalink / raw)
  To: David Ahern; +Cc: linux-perf-users, linux-kernel

Em Tue, Dec 14, 2010 at 10:52:45AM -0200, Arnaldo Carvalho de Melo escreveu:
> Ok, there are still some problems:
> 
> It is escaping the symfs jail for /home/acme/bin/perf, /lib64/libpthread-2.5.so
> and kernel modules, investigating...

Those 'G' signals means DSO__ORIG_GUEST_KMODULE, since you were not
prefixing that case with symfs, it was the jail leak point, fixed, doing
some more testing before merging.

> [acme@mica linux]$ find /tmp/bla
> /tmp/bla
> /tmp/bla/lib64
> /tmp/bla/lib64/libc-2.5.so
> [acme@mica linux]$ perf report -v -g none --stdio --symfs /tmp/bla
> Failed to open [kernel.kallsyms], continuing without symbols
> # Events: 503  cycles
> #
> # Overhead Command    Shared Object                                Symbol
> # ........ .......... .....................................        ....................
> #
>    0.84%        perf  /home/acme/bin/perf                  0x26bf1 G [.] die_builtin
>    0.21%        perf  /home/acme/bin/perf                  0x1db4b G [.] event__synthesize_kernel_mmap
>    0.21%        perf  /home/acme/bin/perf                  0x4700  G [.] _init
>    0.21%        perf  /home/acme/bin/perf                  0x1deca G [.] event__synthesize_comm
>    0.21%        perf  /lib64/libpthread-2.5.so             0xd210  G [.] __write_nocancel
>    0.21%        perf  /home/acme/bin/perf                  0xddbd  G [.] atexit_header
>    0.03% kworker/0:1  /lib/modules/2.6.37-rc3/.../ixgbe.ko 0x605   G [k] ixgbe_update_stats

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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-14 12:52   ` Arnaldo Carvalho de Melo
  2010-12-14 14:06     ` Arnaldo Carvalho de Melo
@ 2010-12-14 14:27     ` David S. Ahern
  2010-12-14 14:35       ` Arnaldo Carvalho de Melo
  1 sibling, 1 reply; 9+ messages in thread
From: David S. Ahern @ 2010-12-14 14:27 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users, linux-kernel



On 12/14/10 05:52, Arnaldo Carvalho de Melo wrote:
> Em Tue, Dec 14, 2010 at 10:24:28AM -0200, Arnaldo Carvalho de Melo escreveu:
>> Em Thu, Dec 09, 2010 at 01:27:07PM -0700, David Ahern escreveu:
>>> The symfs argument allows analysis of perf.data file using a locally
>>> accessible filesystem tree with debug symbols - e.g., tree created
>>> during image builds, sshfs mount, loop mounted KVM disk images,
>>> USB keys, initrds, etc. Anything with an OS tree can be analyzed from
>>> anywhere without the need to populate a local data store with
>>> build-ids.
>>>
>>> Signed-off-by: David Ahern <daahern@cisco.com>
>>>
>>> v2 --> v3: handle symfs="/"
>>
>> [acme@felicio ~]$ ./realpath /..//.
>> /
>> [acme@felicio ~]$
>>
>> I'll fix this up and merge, thanks!

I was not aware of realpath. Simple change to symbol__init?

> 
> Ok, there are still some problems:
> 
> It is escaping the symfs jail for /home/acme/bin/perf, /lib64/libpthread-2.5.so
> and kernel modules, investigating...

> 
> - Arnaldo
> 
> [acme@mica linux]$ find /tmp/bla
> /tmp/bla
> /tmp/bla/lib64
> /tmp/bla/lib64/libc-2.5.so
> [acme@mica linux]$ perf report -v -g none --stdio --symfs /tmp/bla > /tmp/out
> Looking at the vmlinux_path (3 entries long)
> Failed to open [kernel.kallsyms], continuing without symbols
> dso__synthesize_plt_symbols: problems reading /home/acme/bin/perf PLT info.
> dso__synthesize_plt_symbols: problems reading /lib64/libpthread-2.5.so PLT info.
> dso__synthesize_plt_symbols: problems reading /lib/modules/2.6.37-rc3-00084-gd937616/kernel/drivers/net/ixgbe/ixgbe.ko PLT info.
> [acme@mica linux]$ cat /tmp/out

strace -e trace=open /tmp/build-perf/perf report -v --symfs /tmp/f14-mnt
-i /tmp/perf-cs.data

does not show any attempts to open a file not starting with the symfs path.

At the top of dso__synthesize_plt_symbols() is:
	snprintf(name, sizeof(name), "%s%s",
		 symbol_conf.symfs, self->long_name);
	fd = open(name, O_RDONLY);

so the open only gets the relative path.

David

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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-14 14:06     ` Arnaldo Carvalho de Melo
@ 2010-12-14 14:33       ` David S. Ahern
  2010-12-14 14:39         ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 9+ messages in thread
From: David S. Ahern @ 2010-12-14 14:33 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo; +Cc: linux-perf-users, linux-kernel



On 12/14/10 07:06, Arnaldo Carvalho de Melo wrote:
> Em Tue, Dec 14, 2010 at 10:52:45AM -0200, Arnaldo Carvalho de Melo escreveu:
>> Ok, there are still some problems:
>>
>> It is escaping the symfs jail for /home/acme/bin/perf, /lib64/libpthread-2.5.so
>> and kernel modules, investigating...
> 
> Those 'G' signals means DSO__ORIG_GUEST_KMODULE, since you were not
> prefixing that case with symfs, it was the jail leak point, fixed, doing
> some more testing before merging.

yuk. I did not touch the hypervisor paths.

So the 'guest' route is tried all the time because of the origin list --
even when it's not applicable.

David

> 
>> [acme@mica linux]$ find /tmp/bla
>> /tmp/bla
>> /tmp/bla/lib64
>> /tmp/bla/lib64/libc-2.5.so
>> [acme@mica linux]$ perf report -v -g none --stdio --symfs /tmp/bla
>> Failed to open [kernel.kallsyms], continuing without symbols
>> # Events: 503  cycles
>> #
>> # Overhead Command    Shared Object                                Symbol
>> # ........ .......... .....................................        ....................
>> #
>>    0.84%        perf  /home/acme/bin/perf                  0x26bf1 G [.] die_builtin
>>    0.21%        perf  /home/acme/bin/perf                  0x1db4b G [.] event__synthesize_kernel_mmap
>>    0.21%        perf  /home/acme/bin/perf                  0x4700  G [.] _init
>>    0.21%        perf  /home/acme/bin/perf                  0x1deca G [.] event__synthesize_comm
>>    0.21%        perf  /lib64/libpthread-2.5.so             0xd210  G [.] __write_nocancel
>>    0.21%        perf  /home/acme/bin/perf                  0xddbd  G [.] atexit_header
>>    0.03% kworker/0:1  /lib/modules/2.6.37-rc3/.../ixgbe.ko 0x605   G [k] ixgbe_update_stats

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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-14 14:27     ` David S. Ahern
@ 2010-12-14 14:35       ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-12-14 14:35 UTC (permalink / raw)
  To: David S. Ahern; +Cc: linux-perf-users, linux-kernel

Em Tue, Dec 14, 2010 at 07:27:42AM -0700, David S. Ahern escreveu:
> On 12/14/10 05:52, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Dec 14, 2010 at 10:24:28AM -0200, Arnaldo Carvalho de Melo escreveu:
> I was not aware of realpath. Simple change to symbol__init?

I made symbol__init use realpath to reduce the arg to --symfs.
 
> > [acme@mica linux]$ find /tmp/bla
> > /tmp/bla
> > /tmp/bla/lib64
> > /tmp/bla/lib64/libc-2.5.so
> > [acme@mica linux]$ perf report -v -g none --stdio --symfs /tmp/bla > /tmp/out
> > Looking at the vmlinux_path (3 entries long)
> > Failed to open [kernel.kallsyms], continuing without symbols
> > dso__synthesize_plt_symbols: problems reading /home/acme/bin/perf PLT info.
> > [acme@mica linux]$ cat /tmp/out

> strace -e trace=open /tmp/build-perf/perf report -v --symfs /tmp/f14-mnt
> -i /tmp/perf-cs.data

> does not show any attempts to open a file not starting with the symfs path.

Probably because all the files you need are in the directories you
passed to --symfs, remove one and it will leak.

Anyway, fixed in my perf/core branch, still not propagated from
master.k.o to git.k.o :-\

- Arnaldo

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

* Re: [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree
  2010-12-14 14:33       ` David S. Ahern
@ 2010-12-14 14:39         ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2010-12-14 14:39 UTC (permalink / raw)
  To: David S. Ahern; +Cc: linux-perf-users, linux-kernel

Em Tue, Dec 14, 2010 at 07:33:27AM -0700, David S. Ahern escreveu:
> On 12/14/10 07:06, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Dec 14, 2010 at 10:52:45AM -0200, Arnaldo Carvalho de Melo escreveu:
> >> Ok, there are still some problems:

> >> It is escaping the symfs jail for /home/acme/bin/perf, /lib64/libpthread-2.5.so
> >> and kernel modules, investigating...

> > Those 'G' signals means DSO__ORIG_GUEST_KMODULE, since you were not
> > prefixing that case with symfs, it was the jail leak point, fixed, doing
> > some more testing before merging.

> yuk. I did not touch the hypervisor paths.

> So the 'guest' route is tried all the time because of the origin list --
> even when it's not applicable.

Right, I don't like the way kvm is supported, will revisit this at some
point.

If build-ids were first class citizens, all this would be moot :-\

- Arnaldo

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

* [tip:perf/core] perf symbols: Add symfs option for off-box analysis using specified tree
  2010-12-09 20:27 [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree David Ahern
  2010-12-14 12:24 ` Arnaldo Carvalho de Melo
@ 2010-12-22 11:29 ` tip-bot for David Ahern
  1 sibling, 0 replies; 9+ messages in thread
From: tip-bot for David Ahern @ 2010-12-22 11:29 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: acme, linux-kernel, hpa, mingo, tglx, daahern

Commit-ID:  ec5761eab318e50e69fcf8e63e9edaef5949c067
Gitweb:     http://git.kernel.org/tip/ec5761eab318e50e69fcf8e63e9edaef5949c067
Author:     David Ahern <daahern@cisco.com>
AuthorDate: Thu, 9 Dec 2010 13:27:07 -0700
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 21 Dec 2010 20:17:51 -0200

perf symbols: Add symfs option for off-box analysis using specified tree

The symfs argument allows analysis of perf.data file using a locally accessible
filesystem tree with debug symbols - e.g., tree created during image builds,
sshfs mount, loop mounted KVM disk images, USB keys, initrds, etc. Anything
with an OS tree can be analyzed from anywhere without the need to populate a
local data store with build-ids.

Commiter notes:

o Fixed up symfs="/" variants handling.

o prefixed DSO__ORIG_GUEST_KMODULE case with symfs too, avoiding use of files
  outside the symfs directory.

LKML-Reference: <1291926427-28846-1-git-send-email-daahern@cisco.com>
Signed-off-by: David Ahern <daahern@cisco.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-diff.txt      |    2 +
 tools/perf/Documentation/perf-report.txt    |    3 +
 tools/perf/Documentation/perf-timechart.txt |    2 +
 tools/perf/builtin-diff.c                   |    2 +
 tools/perf/builtin-report.c                 |    2 +
 tools/perf/builtin-timechart.c              |    2 +
 tools/perf/util/hist.c                      |   14 ++++-
 tools/perf/util/symbol.c                    |   72 +++++++++++++++++++++------
 tools/perf/util/symbol.h                    |    1 +
 9 files changed, 81 insertions(+), 19 deletions(-)

diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt
index 6a9ec2b..74d7481 100644
--- a/tools/perf/Documentation/perf-diff.txt
+++ b/tools/perf/Documentation/perf-diff.txt
@@ -66,6 +66,8 @@ OPTIONS
 --force::
        Don't complain, do it.
 
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
 
 SEE ALSO
 --------
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index fefea77..8ba03d6 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -116,6 +116,9 @@ OPTIONS
 --force::
         Don't complain, do it.
 
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1]
diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt
index 4b17883..d7b79e2 100644
--- a/tools/perf/Documentation/perf-timechart.txt
+++ b/tools/perf/Documentation/perf-timechart.txt
@@ -38,6 +38,8 @@ OPTIONS
 --process::
         Select the processes to display, by name or PID
 
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
 
 SEE ALSO
 --------
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 97846dc..3153e49 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -194,6 +194,8 @@ static const struct option options[] = {
 	OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
 		   "separator for columns, no spaces will be added between "
 		   "columns '.' is reserved."),
+	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+		    "Look for files with symbols relative to this directory"),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 4af7ce6..75183a4 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -483,6 +483,8 @@ static const struct option options[] = {
 		   "columns '.' is reserved."),
 	OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
 		    "Only display entries resolved to a symbol"),
+	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+		    "Look for files with symbols relative to this directory"),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 459b5e3..d75084b 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1022,6 +1022,8 @@ static const struct option options[] = {
 	OPT_CALLBACK('p', "process", NULL, "process",
 		      "process selector. Pass a pid or process name.",
 		       parse_process),
+	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+		    "Look for files with symbols relative to this directory"),
 	OPT_END()
 };
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index a3b8416..d503670 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1092,6 +1092,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 	FILE *file;
 	int err = 0;
 	u64 len;
+	char symfs_filename[PATH_MAX];
+
+	if (filename) {
+		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
+			 symbol_conf.symfs, filename);
+	}
 
 	if (filename == NULL) {
 		if (dso->has_build_id) {
@@ -1100,9 +1106,9 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 			return -ENOMEM;
 		}
 		goto fallback;
-	} else if (readlink(filename, command, sizeof(command)) < 0 ||
+	} else if (readlink(symfs_filename, command, sizeof(command)) < 0 ||
 		   strstr(command, "[kernel.kallsyms]") ||
-		   access(filename, R_OK)) {
+		   access(symfs_filename, R_OK)) {
 		free(filename);
 fallback:
 		/*
@@ -1111,6 +1117,8 @@ fallback:
 		 * DSO is the same as when 'perf record' ran.
 		 */
 		filename = dso->long_name;
+		snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
+			 symbol_conf.symfs, filename);
 		free_filename = false;
 	}
 
@@ -1137,7 +1145,7 @@ fallback:
 		 "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
 		 map__rip_2objdump(map, sym->start),
 		 map__rip_2objdump(map, sym->end),
-		 filename, filename);
+		 symfs_filename, filename);
 
 	pr_debug("Executing: %s\n", command);
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ceefa65..561db63 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -41,6 +41,7 @@ struct symbol_conf symbol_conf = {
 	.exclude_other	  = true,
 	.use_modules	  = true,
 	.try_vmlinux_path = true,
+	.symfs            = "",
 };
 
 int dso__name_len(const struct dso *self)
@@ -839,8 +840,11 @@ static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
 	char sympltname[1024];
 	Elf *elf;
 	int nr = 0, symidx, fd, err = 0;
+	char name[PATH_MAX];
 
-	fd = open(self->long_name, O_RDONLY);
+	snprintf(name, sizeof(name), "%s%s",
+		 symbol_conf.symfs, self->long_name);
+	fd = open(name, O_RDONLY);
 	if (fd < 0)
 		goto out;
 
@@ -1452,16 +1456,19 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 	     self->origin++) {
 		switch (self->origin) {
 		case DSO__ORIG_BUILD_ID_CACHE:
-			if (dso__build_id_filename(self, name, size) == NULL)
+			/* skip the locally configured cache if a symfs is given */
+			if (symbol_conf.symfs[0] ||
+			    (dso__build_id_filename(self, name, size) == NULL)) {
 				continue;
+			}
 			break;
 		case DSO__ORIG_FEDORA:
-			snprintf(name, size, "/usr/lib/debug%s.debug",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s.debug",
+				 symbol_conf.symfs, self->long_name);
 			break;
 		case DSO__ORIG_UBUNTU:
-			snprintf(name, size, "/usr/lib/debug%s",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s",
+				 symbol_conf.symfs, self->long_name);
 			break;
 		case DSO__ORIG_BUILDID: {
 			char build_id_hex[BUILD_ID_SIZE * 2 + 1];
@@ -1473,19 +1480,26 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 					  sizeof(self->build_id),
 					  build_id_hex);
 			snprintf(name, size,
-				 "/usr/lib/debug/.build-id/%.2s/%s.debug",
-				 build_id_hex, build_id_hex + 2);
+				 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+				 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
 			}
 			break;
 		case DSO__ORIG_DSO:
-			snprintf(name, size, "%s", self->long_name);
+			snprintf(name, size, "%s%s",
+			     symbol_conf.symfs, self->long_name);
 			break;
 		case DSO__ORIG_GUEST_KMODULE:
 			if (map->groups && map->groups->machine)
 				root_dir = map->groups->machine->root_dir;
 			else
 				root_dir = "";
-			snprintf(name, size, "%s%s", root_dir, self->long_name);
+			snprintf(name, size, "%s%s%s", symbol_conf.symfs,
+				 root_dir, self->long_name);
+			break;
+
+		case DSO__ORIG_KMODULE:
+			snprintf(name, size, "%s%s", symbol_conf.symfs,
+				 self->long_name);
 			break;
 
 		default:
@@ -1784,17 +1798,20 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
 			     const char *vmlinux, symbol_filter_t filter)
 {
 	int err = -1, fd;
+	char symfs_vmlinux[PATH_MAX];
 
-	fd = open(vmlinux, O_RDONLY);
+	snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s/%s",
+		 symbol_conf.symfs, vmlinux);
+	fd = open(symfs_vmlinux, O_RDONLY);
 	if (fd < 0)
 		return -1;
 
 	dso__set_loaded(self, map->type);
-	err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
+	err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0);
 	close(fd);
 
 	if (err > 0)
-		pr_debug("Using %s for symbols\n", vmlinux);
+		pr_debug("Using %s for symbols\n", symfs_vmlinux);
 
 	return err;
 }
@@ -1872,6 +1889,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
 			goto out_fixup;
 	}
 
+	/* do not try local files if a symfs was given */
+	if (symbol_conf.symfs[0] != 0)
+		return -1;
+
 	/*
 	 * Say the kernel DSO was created when processing the build-id header table,
 	 * we have a build-id, so check if it is the same as the running kernel,
@@ -2262,9 +2283,6 @@ static int vmlinux_path__init(void)
 	struct utsname uts;
 	char bf[PATH_MAX];
 
-	if (uname(&uts) < 0)
-		return -1;
-
 	vmlinux_path = malloc(sizeof(char *) * 5);
 	if (vmlinux_path == NULL)
 		return -1;
@@ -2277,6 +2295,14 @@ static int vmlinux_path__init(void)
 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
 		goto out_fail;
 	++vmlinux_path__nr_entries;
+
+	/* only try running kernel version if no symfs was given */
+	if (symbol_conf.symfs[0] != 0)
+		return 0;
+
+	if (uname(&uts) < 0)
+		return -1;
+
 	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
 	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
@@ -2336,6 +2362,8 @@ static int setup_list(struct strlist **list, const char *list_str,
 
 int symbol__init(void)
 {
+	const char *symfs;
+
 	if (symbol_conf.initialized)
 		return 0;
 
@@ -2364,6 +2392,18 @@ int symbol__init(void)
 		       symbol_conf.sym_list_str, "symbol") < 0)
 		goto out_free_comm_list;
 
+	/*
+	 * A path to symbols of "/" is identical to ""
+	 * reset here for simplicity.
+	 */
+	symfs = realpath(symbol_conf.symfs, NULL);
+	if (symfs == NULL)
+		symfs = symbol_conf.symfs;
+	if (strcmp(symfs, "/") == 0)
+		symbol_conf.symfs = "";
+	if (symfs != symbol_conf.symfs)
+		free((void *)symfs);
+
 	symbol_conf.initialized = true;
 	return 0;
 
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 12defbe..bcd2f98 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -86,6 +86,7 @@ struct symbol_conf {
        struct strlist	*dso_list,
 			*comm_list,
 			*sym_list;
+	const char	*symfs;
 };
 
 extern struct symbol_conf symbol_conf;

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

end of thread, other threads:[~2010-12-22 11:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-09 20:27 [PATCH v3] perf tools: Add symfs option for off-box analysis using specified tree David Ahern
2010-12-14 12:24 ` Arnaldo Carvalho de Melo
2010-12-14 12:52   ` Arnaldo Carvalho de Melo
2010-12-14 14:06     ` Arnaldo Carvalho de Melo
2010-12-14 14:33       ` David S. Ahern
2010-12-14 14:39         ` Arnaldo Carvalho de Melo
2010-12-14 14:27     ` David S. Ahern
2010-12-14 14:35       ` Arnaldo Carvalho de Melo
2010-12-22 11:29 ` [tip:perf/core] perf symbols: " tip-bot for David Ahern

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.