diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2009-12-15 20:04:41 -0200 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-12-16 08:53:49 +0100 |
commit | c410a33887c17cac95ed8b0d860cdfb5c087a7d8 (patch) | |
tree | 54fe6ed5ac64ff77763ff686af58bd36b04e73d6 /tools/perf/util | |
parent | 655000e7c75a559681ee7f15f6fa870c80ae3194 (diff) | |
download | kernel-crypto-c410a33887c17cac95ed8b0d860cdfb5c087a7d8.tar.gz kernel-crypto-c410a33887c17cac95ed8b0d860cdfb5c087a7d8.tar.xz kernel-crypto-c410a33887c17cac95ed8b0d860cdfb5c087a7d8.zip |
perf symbols: Move symbol filtering to event__preprocess_sample()
So that --dsos, --comm, --symbols can bem used in more tools,
like in perf diff:
$ perf record -f find / > /dev/null
$ perf record -f find / > /dev/null
$ perf diff --dsos /lib64/libc-2.10.1.so | head -5
1 +22392124 /lib64/libc-2.10.1.so _IO_vfprintf_internal
2 +6410655 /lib64/libc-2.10.1.so __GI_memmove
3 +1 +9192692 /lib64/libc-2.10.1.so _int_malloc
4 -1 -15158605 /lib64/libc-2.10.1.so _int_free
5 +45669 /lib64/libc-2.10.1.so _IO_new_file_xsputn
$
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260914682-29652-3-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/event.c | 42 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 5 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 4 |
3 files changed, 50 insertions, 1 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 375fb6dca1c..bf491fda1f4 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -2,7 +2,9 @@ #include "event.h" #include "debug.h" #include "session.h" +#include "sort.h" #include "string.h" +#include "strlist.h" #include "thread.h" static pid_t event__synthesize_comm(pid_t pid, int full, @@ -299,6 +301,19 @@ try_again: } } +static void dso__calc_col_width(struct dso *self) +{ + if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep && + (!symbol_conf.dso_list || + strlist__has_entry(symbol_conf.dso_list, self->name))) { + unsigned int slen = strlen(self->name); + if (slen > dsos__col_width) + dsos__col_width = slen; + } + + self->slen_calculated = 1; +} + int event__preprocess_sample(const event_t *self, struct perf_session *session, struct addr_location *al, symbol_filter_t filter) { @@ -308,6 +323,10 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, if (thread == NULL) return -1; + if (symbol_conf.comm_list && + !strlist__has_entry(symbol_conf.comm_list, thread->comm)) + goto out_filtered; + dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION, @@ -315,6 +334,29 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, dump_printf(" ...... dso: %s\n", al->map ? al->map->dso->long_name : al->level == 'H' ? "[hypervisor]" : "<not found>"); + /* + * We have to do this here as we may have a dso with no symbol hit that + * has a name longer than the ones with symbols sampled. + */ + if (al->map && !sort_dso.elide && !al->map->dso->slen_calculated) + dso__calc_col_width(al->map->dso); + + if (symbol_conf.dso_list && + (!al->map || !al->map->dso || + !(strlist__has_entry(symbol_conf.dso_list, al->map->dso->short_name) || + (al->map->dso->short_name != al->map->dso->long_name && + strlist__has_entry(symbol_conf.dso_list, al->map->dso->long_name))))) + goto out_filtered; + + if (symbol_conf.sym_list && al->sym && + !strlist__has_entry(symbol_conf.sym_list, al->sym->name)) + goto out_filtered; + + al->filtered = false; + return 0; + +out_filtered: + al->filtered = true; return 0; } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 164286ace7d..7707897b59f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1764,6 +1764,11 @@ int symbol__init(void) if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0) return -1; + if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') { + pr_err("'.' is the only non valid --field-separator argument\n"); + return -1; + } + if (setup_list(&symbol_conf.dso_list, symbol_conf.dso_list_str, "dso") < 0) return -1; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index d61f3507499..60151521f41 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -56,7 +56,8 @@ struct symbol_conf { bool try_vmlinux_path, use_modules, sort_by_name; - const char *vmlinux_name; + const char *vmlinux_name, + *field_sep; char *dso_list_str, *comm_list_str, *sym_list_str, @@ -79,6 +80,7 @@ struct addr_location { struct symbol *sym; u64 addr; char level; + bool filtered; }; struct dso { |