From: Arnaldo Carvalho de Melo <[email protected]>
This simplifies a lot of functions, less stuff to be done by tool
writers.
Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 14 +++++-------
tools/perf/builtin-buildid-list.c | 5 ++-
tools/perf/builtin-diff.c | 8 ++----
tools/perf/builtin-kmem.c | 5 +--
tools/perf/builtin-probe.c | 14 +++++-------
tools/perf/builtin-record.c | 4 +-
tools/perf/builtin-report.c | 7 +----
tools/perf/builtin-sched.c | 5 +--
tools/perf/builtin-timechart.c | 5 +--
tools/perf/builtin-top.c | 6 +---
tools/perf/builtin-trace.c | 4 +-
tools/perf/util/session.c | 5 +--
tools/perf/util/session.h | 5 +---
tools/perf/util/symbol.c | 38 ++++++++++++++----------------------
tools/perf/util/symbol.h | 9 +++----
15 files changed, 54 insertions(+), 80 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 2e2855a..e656e25 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -51,11 +51,6 @@ struct sym_priv {
struct sym_ext *ext;
};
-static struct symbol_conf symbol_conf = {
- .priv_size = sizeof(struct sym_priv),
- .try_vmlinux_path = true,
-};
-
static const char *sym_hist_filter;
static int symbol_filter(struct map *map __used, struct symbol *sym)
@@ -464,10 +459,10 @@ static struct perf_event_ops event_ops = {
static int __cmd_annotate(void)
{
- struct perf_session *session = perf_session__new(input_name, O_RDONLY,
- force, &symbol_conf);
int ret;
+ struct perf_session *session;
+ session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
return -ENOMEM;
@@ -523,7 +518,10 @@ static const struct option options[] = {
int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
- if (symbol__init(&symbol_conf) < 0)
+ symbol_conf.priv_size = sizeof(struct sym_priv);
+ symbol_conf.try_vmlinux_path = true;
+
+ if (symbol__init() < 0)
return -1;
argc = parse_options(argc, argv, options, annotate_usage, 0);
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 7c36e4b..e693e67 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -54,8 +54,9 @@ static int perf_file_section__process_buildids(struct perf_file_section *self,
static int __cmd_buildid_list(void)
{
int err = -1;
- struct perf_session *session = perf_session__new(input_name, O_RDONLY,
- force, NULL);
+ struct perf_session *session;
+
+ session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 0d52801..67328d1 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -21,8 +21,6 @@ static char const *input_old = "perf.data.old",
static int force;
static bool show_percent;
-struct symbol_conf symbol_conf;
-
static int perf_session__add_hist_entry(struct perf_session *self,
struct addr_location *al, u64 count)
{
@@ -226,8 +224,8 @@ static int __cmd_diff(void)
int ret, i;
struct perf_session *session[2];
- session[0] = perf_session__new(input_old, O_RDONLY, force, &symbol_conf);
- session[1] = perf_session__new(input_new, O_RDONLY, force, &symbol_conf);
+ session[0] = perf_session__new(input_old, O_RDONLY, force);
+ session[1] = perf_session__new(input_new, O_RDONLY, force);
if (session[0] == NULL || session[1] == NULL)
return -ENOMEM;
@@ -267,7 +265,7 @@ static const struct option options[] = {
int cmd_diff(int argc, const char **argv, const char *prefix __used)
{
- if (symbol__init(&symbol_conf) < 0)
+ if (symbol__init() < 0)
return -1;
setup_sorting(diff_usage, options);
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index dda6086..e078797 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -505,8 +505,7 @@ static void sort_result(void)
static int __cmd_kmem(void)
{
int err;
- struct perf_session *session = perf_session__new(input_name, O_RDONLY,
- 0, NULL);
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
if (session == NULL)
return -ENOMEM;
@@ -767,7 +766,7 @@ static int __cmd_record(int argc, const char **argv)
int cmd_kmem(int argc, const char **argv, const char *prefix __used)
{
- symbol__init(0);
+ symbol__init();
argc = parse_options(argc, argv, kmem_options, kmem_usage, 0);
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 520b064..7e741f5 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -57,7 +57,6 @@ static struct {
int nr_probe;
struct probe_point probes[MAX_PROBES];
struct strlist *dellist;
- struct symbol_conf conf;
struct perf_session *psession;
struct map *kmap;
} session;
@@ -151,7 +150,7 @@ static const struct option options[] = {
OPT_BOOLEAN('v', "verbose", &verbose,
"be more verbose (show parsed arguments, etc)"),
#ifndef NO_LIBDWARF
- OPT_STRING('k', "vmlinux", &session.conf.vmlinux_name,
+ OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
"file", "vmlinux pathname"),
#endif
OPT_BOOLEAN('l', "list", &session.list_events,
@@ -224,13 +223,12 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
}
/* Initialize symbol maps for vmlinux */
- session.conf.sort_by_name = true;
- if (session.conf.vmlinux_name == NULL)
- session.conf.try_vmlinux_path = true;
- if (symbol__init(&session.conf) < 0)
+ symbol_conf.sort_by_name = true;
+ if (symbol_conf.vmlinux_name == NULL)
+ symbol_conf.try_vmlinux_path = true;
+ if (symbol__init() < 0)
die("Failed to init symbol map.");
- session.psession = perf_session__new(NULL, O_WRONLY, false,
- &session.conf);
+ session.psession = perf_session__new(NULL, O_WRONLY, false);
if (session.psession == NULL)
die("Failed to init perf_session.");
session.kmap = map_groups__find_by_name(&session.psession->kmaps,
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 66979a5..1da48a8 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -451,7 +451,7 @@ static int __cmd_record(int argc, const char **argv)
exit(-1);
}
- session = perf_session__new(output_name, O_WRONLY, force, NULL);
+ session = perf_session__new(output_name, O_WRONLY, force);
if (session == NULL) {
pr_err("Not enough memory for reading perf file header\n");
return -1;
@@ -632,7 +632,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
{
int counter;
- symbol__init(0);
+ symbol__init();
argc = parse_options(argc, argv, options, record_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 40389c0..c349bdb 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -52,9 +52,6 @@ static int exclude_other = 1;
static char callchain_default_opt[] = "fractal,0.5";
-static struct symbol_conf symbol_conf;
-
-
static size_t
callchain__fprintf_left_margin(FILE *fp, int left_margin)
{
@@ -705,7 +702,7 @@ static int __cmd_report(void)
int ret;
struct perf_session *session;
- session = perf_session__new(input_name, O_RDONLY, force, &symbol_conf);
+ session = perf_session__new(input_name, O_RDONLY, force);
if (session == NULL)
return -ENOMEM;
@@ -864,7 +861,7 @@ static void setup_list(struct strlist **list, const char *list_str,
int cmd_report(int argc, const char **argv, const char *prefix __used)
{
- if (symbol__init(&symbol_conf) < 0)
+ if (symbol__init() < 0)
return -1;
argc = parse_options(argc, argv, options, report_usage, 0);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index d67f274..80209df 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1675,8 +1675,7 @@ static struct perf_event_ops event_ops = {
static int read_events(void)
{
int err;
- struct perf_session *session = perf_session__new(input_name, O_RDONLY,
- 0, NULL);
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
if (session == NULL)
return -ENOMEM;
@@ -1912,7 +1911,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __used)
if (!strcmp(argv[0], "trace"))
return cmd_trace(argc, argv, prefix);
- symbol__init(0);
+ symbol__init();
if (!strncmp(argv[0], "rec", 3)) {
return __cmd_record(argc, argv);
} else if (!strncmp(argv[0], "lat", 3)) {
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index ffd81e8..9c98b7a 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1050,8 +1050,7 @@ static struct perf_event_ops event_ops = {
static int __cmd_timechart(void)
{
- struct perf_session *session = perf_session__new(input_name, O_RDONLY,
- 0, NULL);
+ struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
int ret;
if (session == NULL)
@@ -1138,7 +1137,7 @@ static const struct option options[] = {
int cmd_timechart(int argc, const char **argv, const char *prefix __used)
{
- symbol__init(0);
+ symbol__init();
argc = parse_options(argc, argv, options, timechart_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 296e809..cd89b6d 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -80,7 +80,6 @@ static int dump_symtab = 0;
static bool hide_kernel_symbols = false;
static bool hide_user_symbols = false;
static struct winsize winsize;
-static struct symbol_conf symbol_conf;
/*
* Source
@@ -1162,8 +1161,7 @@ static int __cmd_top(void)
* FIXME: perf_session__new should allow passing a O_MMAP, so that all this
* mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
*/
- struct perf_session *session = perf_session__new(NULL, O_WRONLY, false,
- &symbol_conf);
+ struct perf_session *session = perf_session__new(NULL, O_WRONLY, false);
if (session == NULL)
return -ENOMEM;
@@ -1284,7 +1282,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
(nr_counters + 1) * sizeof(unsigned long));
if (symbol_conf.vmlinux_name == NULL)
symbol_conf.try_vmlinux_path = true;
- if (symbol__init(&symbol_conf) < 0)
+ if (symbol__init() < 0)
return -1;
if (delay_secs < 1)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 7e744f7..07ad25c 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -579,7 +579,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
exit(-1);
}
- symbol__init(0);
+ symbol__init();
setup_scripting();
@@ -588,7 +588,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
setup_pager();
- session = perf_session__new(input_name, O_RDONLY, 0, NULL);
+ session = perf_session__new(input_name, O_RDONLY, 0);
if (session == NULL)
return -ENOMEM;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index ecd54be..bceaa09 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -49,8 +49,7 @@ out_close:
return -1;
}
-struct perf_session *perf_session__new(const char *filename, int mode,
- bool force, struct symbol_conf *conf)
+struct perf_session *perf_session__new(const char *filename, int mode, bool force)
{
size_t len = filename ? strlen(filename) + 1 : 0;
struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -69,7 +68,7 @@ struct perf_session *perf_session__new(const char *filename, int mode,
self->cwdlen = 0;
map_groups__init(&self->kmaps);
- if (perf_session__create_kernel_maps(self, conf) < 0)
+ if (perf_session__create_kernel_maps(self) < 0)
goto out_delete;
if (mode == O_RDONLY && perf_session__open(self, force) < 0)
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index bdfc4b8..faf18a8 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -10,7 +10,6 @@
struct ip_callchain;
struct thread;
struct symbol;
-struct symbol_conf;
struct perf_session {
struct perf_header header;
@@ -26,7 +25,6 @@ struct perf_session {
int fd;
int cwdlen;
char *cwd;
- bool use_modules;
bool use_callchain;
char filename[0];
};
@@ -48,8 +46,7 @@ struct perf_event_ops {
bool full_paths;
};
-struct perf_session *perf_session__new(const char *filename, int mode,
- bool force, struct symbol_conf *conf);
+struct perf_session *perf_session__new(const char *filename, int mode, bool force);
void perf_session__delete(struct perf_session *self);
int perf_session__process_events(struct perf_session *self,
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 185b9ee..17ce012 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -33,11 +33,10 @@ static void dsos__add(struct list_head *head, struct dso *dso);
static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
static int dso__load_kernel_sym(struct dso *self, struct map *map,
struct perf_session *session, symbol_filter_t filter);
-unsigned int symbol__priv_size;
static int vmlinux_path__nr_entries;
static char **vmlinux_path;
-static struct symbol_conf symbol_conf__defaults = {
+struct symbol_conf symbol_conf = {
.use_modules = true,
.try_vmlinux_path = true,
};
@@ -130,13 +129,13 @@ static void map_groups__fixup_end(struct map_groups *self)
static struct symbol *symbol__new(u64 start, u64 len, const char *name)
{
size_t namelen = strlen(name) + 1;
- struct symbol *self = zalloc(symbol__priv_size +
+ struct symbol *self = zalloc(symbol_conf.priv_size +
sizeof(*self) + namelen);
if (self == NULL)
return NULL;
- if (symbol__priv_size)
- self = ((void *)self) + symbol__priv_size;
+ if (symbol_conf.priv_size)
+ self = ((void *)self) + symbol_conf.priv_size;
self->start = start;
self->end = len ? start + len - 1 : start;
@@ -150,7 +149,7 @@ static struct symbol *symbol__new(u64 start, u64 len, const char *name)
static void symbol__delete(struct symbol *self)
{
- free(((void *)self) - symbol__priv_size);
+ free(((void *)self) - symbol_conf.priv_size);
}
static size_t symbol__fprintf(struct symbol *self, FILE *fp)
@@ -471,7 +470,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map,
module = strchr(pos->name, '\t');
if (module) {
- if (!session->use_modules)
+ if (!symbol_conf.use_modules)
goto discard_symbol;
*module++ = '\0';
@@ -1740,34 +1739,27 @@ out_fail:
return -1;
}
-int symbol__init(struct symbol_conf *conf)
+int symbol__init(void)
{
- const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
-
elf_version(EV_CURRENT);
- symbol__priv_size = pconf->priv_size;
- if (pconf->sort_by_name)
- symbol__priv_size += (sizeof(struct symbol_name_rb_node) -
- sizeof(struct symbol));
+ if (symbol_conf.sort_by_name)
+ symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
+ sizeof(struct symbol));
- if (pconf->try_vmlinux_path && vmlinux_path__init() < 0)
+ if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
return -1;
return 0;
}
-int perf_session__create_kernel_maps(struct perf_session *self,
- struct symbol_conf *conf)
+int perf_session__create_kernel_maps(struct perf_session *self)
{
- const struct symbol_conf *pconf = conf ?: &symbol_conf__defaults;
-
if (map_groups__create_kernel_maps(&self->kmaps,
- pconf->vmlinux_name) < 0)
+ symbol_conf.vmlinux_name) < 0)
return -1;
- self->use_modules = pconf->use_modules;
-
- if (pconf->use_modules && perf_session__create_module_maps(self) < 0)
+ if (symbol_conf.use_modules &&
+ perf_session__create_module_maps(self) < 0)
pr_debug("Failed to load list of modules for session %s, "
"continuing...\n", self->filename);
/*
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 941ef33..7662947 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -57,11 +57,11 @@ struct symbol_conf {
const char *vmlinux_name;
};
-extern unsigned int symbol__priv_size;
+extern struct symbol_conf symbol_conf;
static inline void *symbol__priv(struct symbol *self)
{
- return ((void *)self) - symbol__priv_size;
+ return ((void *)self) - symbol_conf.priv_size;
}
struct addr_location {
@@ -119,9 +119,8 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
bool dsos__read_build_ids(void);
int build_id__sprintf(u8 *self, int len, char *bf);
-int symbol__init(struct symbol_conf *conf);
-int perf_session__create_kernel_maps(struct perf_session *self,
- struct symbol_conf *conf);
+int symbol__init(void);
+int perf_session__create_kernel_maps(struct perf_session *self);
extern struct list_head dsos__user, dsos__kernel;
extern struct dso *vdso;
--
1.6.2.5
From: Arnaldo Carvalho de Melo <[email protected]>
Will be used in perf diff too.
Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 4 +-
tools/perf/builtin-diff.c | 9 ++---
tools/perf/builtin-kmem.c | 4 +-
tools/perf/builtin-record.c | 6 ++--
tools/perf/builtin-report.c | 73 +++++++++++++++++----------------------
tools/perf/builtin-timechart.c | 4 +-
tools/perf/builtin-trace.c | 4 +-
tools/perf/util/symbol.c | 33 ++++++++++++++++++
tools/perf/util/symbol.h | 9 +++++
9 files changed, 89 insertions(+), 57 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index e656e25..645d580 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -518,14 +518,14 @@ static const struct option options[] = {
int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
+ argc = parse_options(argc, argv, options, annotate_usage, 0);
+
symbol_conf.priv_size = sizeof(struct sym_priv);
symbol_conf.try_vmlinux_path = true;
if (symbol__init() < 0)
return -1;
- argc = parse_options(argc, argv, options, annotate_usage, 0);
-
setup_sorting(annotate_usage, options);
if (argc) {
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 67328d1..4fde606 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -265,11 +265,6 @@ static const struct option options[] = {
int cmd_diff(int argc, const char **argv, const char *prefix __used)
{
- if (symbol__init() < 0)
- return -1;
-
- setup_sorting(diff_usage, options);
-
argc = parse_options(argc, argv, options, diff_usage, 0);
if (argc) {
if (argc > 2)
@@ -281,6 +276,10 @@ int cmd_diff(int argc, const char **argv, const char *prefix __used)
input_new = argv[0];
}
+ if (symbol__init() < 0)
+ return -1;
+
+ setup_sorting(diff_usage, options);
setup_pager();
return __cmd_diff();
}
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index e078797..fc21ad7 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -766,13 +766,13 @@ static int __cmd_record(int argc, const char **argv)
int cmd_kmem(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
-
argc = parse_options(argc, argv, kmem_options, kmem_usage, 0);
if (!argc)
usage_with_options(kmem_usage, kmem_options);
+ symbol__init();
+
if (!strncmp(argv[0], "rec", 3)) {
return __cmd_record(argc, argv);
} else if (!strcmp(argv[0], "stat")) {
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 1da48a8..65301c5 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -632,13 +632,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
{
int counter;
- symbol__init();
-
argc = parse_options(argc, argv, options, record_usage,
- PARSE_OPT_STOP_AT_NON_OPTION);
+ PARSE_OPT_STOP_AT_NON_OPTION);
if (!argc && target_pid == -1 && !system_wide)
usage_with_options(record_usage, options);
+ symbol__init();
+
if (!nr_counters) {
nr_counters = 1;
attrs[0].type = PERF_TYPE_HARDWARE;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c349bdb..03afac3 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -33,10 +33,6 @@
static char const *input_name = "perf.data";
-static char *dso_list_str, *comm_list_str, *sym_list_str,
- *col_width_list_str;
-static struct strlist *dso_list, *comm_list, *sym_list;
-
static int force;
static bool use_callchain;
@@ -365,8 +361,9 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
static void dso__calc_col_width(struct dso *self)
{
- if (!col_width_list_str && !field_sep &&
- (!dso_list || strlist__has_entry(dso_list, self->name))) {
+ if (!symbol_conf.col_width_list_str && !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;
@@ -379,8 +376,9 @@ static void thread__comm_adjust(struct thread *self)
{
char *comm = self->comm;
- if (!col_width_list_str && !field_sep &&
- (!comm_list || strlist__has_entry(comm_list, comm))) {
+ if (!symbol_conf.col_width_list_str && !field_sep &&
+ (!symbol_conf.comm_list ||
+ strlist__has_entry(symbol_conf.comm_list, comm))) {
unsigned int slen = strlen(comm);
if (slen > comms__col_width) {
@@ -442,7 +440,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
struct rb_node *nd;
size_t ret = 0;
unsigned int width;
- char *col_width = col_width_list_str;
+ char *col_width = symbol_conf.col_width_list_str;
int raw_printing_style;
raw_printing_style = !strcmp(pretty_printing_style, "raw");
@@ -468,7 +466,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
}
width = strlen(se->header);
if (se->width) {
- if (col_width_list_str) {
+ if (symbol_conf.col_width_list_str) {
if (col_width) {
*se->width = atoi(col_width);
col_width = strchr(col_width, ',');
@@ -587,7 +585,8 @@ static int process_sample_event(event_t *event, struct perf_session *session)
dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
- if (comm_list && !strlist__has_entry(comm_list, thread->comm))
+ if (symbol_conf.comm_list &&
+ !strlist__has_entry(symbol_conf.comm_list, thread->comm))
return 0;
cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
@@ -601,14 +600,15 @@ static int process_sample_event(event_t *event, struct perf_session *session)
if (al.map && !sort_dso.elide && !al.map->dso->slen_calculated)
dso__calc_col_width(al.map->dso);
- if (dso_list &&
+ if (symbol_conf.dso_list &&
(!al.map || !al.map->dso ||
- !(strlist__has_entry(dso_list, al.map->dso->short_name) ||
+ !(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(dso_list, al.map->dso->long_name)))))
+ strlist__has_entry(symbol_conf.dso_list, al.map->dso->long_name)))))
return 0;
- if (sym_list && al.sym && !strlist__has_entry(sym_list, al.sym->name))
+ if (symbol_conf.sym_list && al.sym &&
+ !strlist__has_entry(symbol_conf.sym_list, al.sym->name))
return 0;
if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
@@ -825,13 +825,13 @@ static const struct option options[] = {
OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
"Display callchains using output_type and min percent threshold. "
"Default: fractal,0.5", &parse_callchain_opt, callchain_default_opt),
- OPT_STRING('d', "dsos", &dso_list_str, "dso[,dso...]",
+ OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
"only consider symbols in these dsos"),
- OPT_STRING('C', "comms", &comm_list_str, "comm[,comm...]",
+ OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
"only consider symbols in these comms"),
- OPT_STRING('S', "symbols", &sym_list_str, "symbol[,symbol...]",
+ OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
"only consider these symbols"),
- OPT_STRING('w', "column-widths", &col_width_list_str,
+ OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
"width[,width...]",
"don't try to adjust column width, use these fixed values"),
OPT_STRING('t', "field-separator", &field_sep, "separator",
@@ -840,32 +840,25 @@ static const struct option options[] = {
OPT_END()
};
-static void setup_list(struct strlist **list, const char *list_str,
- struct sort_entry *se, const char *list_name,
- FILE *fp)
+static void sort_entry__setup_elide(struct sort_entry *self,
+ struct strlist *list,
+ const char *list_name, FILE *fp)
{
- if (list_str) {
- *list = strlist__new(true, list_str);
- if (!*list) {
- fprintf(stderr, "problems parsing %s list\n",
- list_name);
- exit(129);
- }
- if (strlist__nr_entries(*list) == 1) {
- fprintf(fp, "# %s: %s\n", list_name,
- strlist__entry(*list, 0)->s);
- se->elide = true;
- }
+ if (list && strlist__nr_entries(list) == 1) {
+ fprintf(fp, "# %s: %s\n", list_name, strlist__entry(list, 0)->s);
+ self->elide = true;
}
}
int cmd_report(int argc, const char **argv, const char *prefix __used)
{
+ argc = parse_options(argc, argv, options, report_usage, 0);
+
+ setup_pager();
+
if (symbol__init() < 0)
return -1;
- argc = parse_options(argc, argv, options, report_usage, 0);
-
setup_sorting(report_usage, options);
if (parent_pattern != default_parent_pattern) {
@@ -880,11 +873,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
if (argc)
usage_with_options(report_usage, options);
- setup_pager();
-
- setup_list(&dso_list, dso_list_str, &sort_dso, "dso", stdout);
- setup_list(&comm_list, comm_list_str, &sort_comm, "comm", stdout);
- setup_list(&sym_list, sym_list_str, &sort_sym, "symbol", stdout);
+ sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
+ sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
+ sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
if (field_sep && *field_sep == '.') {
fputs("'.' is the only non valid --field-separator argument\n",
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 9c98b7a..a589a43 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1137,11 +1137,11 @@ static const struct option options[] = {
int cmd_timechart(int argc, const char **argv, const char *prefix __used)
{
- symbol__init();
-
argc = parse_options(argc, argv, options, timechart_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
+ symbol__init();
+
if (argc && !strncmp(argv[0], "rec", 3))
return __cmd_record(argc, argv);
else if (argc)
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 07ad25c..e2285e2 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -579,13 +579,13 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
exit(-1);
}
- symbol__init();
-
setup_scripting();
argc = parse_options(argc, argv, options, annotate_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
+ if (symbol__init() < 0)
+ return -1;
setup_pager();
session = perf_session__new(input_name, O_RDONLY, 0);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 17ce012..164286a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1,6 +1,7 @@
#include "util.h"
#include "../perf.h"
#include "session.h"
+#include "sort.h"
#include "string.h"
#include "symbol.h"
#include "thread.h"
@@ -1739,6 +1740,20 @@ out_fail:
return -1;
}
+static int setup_list(struct strlist **list, const char *list_str,
+ const char *list_name)
+{
+ if (list_str == NULL)
+ return 0;
+
+ *list = strlist__new(true, list_str);
+ if (!*list) {
+ pr_err("problems parsing %s list\n", list_name);
+ return -1;
+ }
+ return 0;
+}
+
int symbol__init(void)
{
elf_version(EV_CURRENT);
@@ -1749,7 +1764,25 @@ int symbol__init(void)
if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
return -1;
+ if (setup_list(&symbol_conf.dso_list,
+ symbol_conf.dso_list_str, "dso") < 0)
+ return -1;
+
+ if (setup_list(&symbol_conf.comm_list,
+ symbol_conf.comm_list_str, "comm") < 0)
+ goto out_free_dso_list;
+
+ if (setup_list(&symbol_conf.sym_list,
+ symbol_conf.sym_list_str, "symbol") < 0)
+ goto out_free_comm_list;
+
return 0;
+
+out_free_dso_list:
+ strlist__delete(symbol_conf.dso_list);
+out_free_comm_list:
+ strlist__delete(symbol_conf.comm_list);
+ return -1;
}
int perf_session__create_kernel_maps(struct perf_session *self)
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 7662947..d61f350 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -49,12 +49,21 @@ struct symbol {
char name[0];
};
+struct strlist;
+
struct symbol_conf {
unsigned short priv_size;
bool try_vmlinux_path,
use_modules,
sort_by_name;
const char *vmlinux_name;
+ char *dso_list_str,
+ *comm_list_str,
+ *sym_list_str,
+ *col_width_list_str;
+ struct strlist *dso_list,
+ *comm_list,
+ *sym_list;
};
extern struct symbol_conf symbol_conf;
--
1.6.2.5
From: Arnaldo Carvalho de Melo <[email protected]>
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
$
Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-annotate.c | 2 +-
tools/perf/builtin-diff.c | 19 ++++++++-
tools/perf/builtin-report.c | 86 ++++++++---------------------------------
tools/perf/builtin-top.c | 2 +-
tools/perf/util/event.c | 42 ++++++++++++++++++++
tools/perf/util/symbol.c | 5 ++
tools/perf/util/symbol.h | 4 +-
7 files changed, 84 insertions(+), 76 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 645d580..593ff25 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -141,7 +141,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
return -1;
}
- if (perf_session__add_hist_entry(session, &al, 1)) {
+ if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) {
fprintf(stderr, "problem incrementing symbol count, "
"skipping event\n");
return -1;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 4fde606..ff91e9c 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -50,6 +50,9 @@ static int diff__process_sample_event(event_t *event, struct perf_session *sessi
return -1;
}
+ if (al.filtered)
+ return 0;
+
event__parse_sample(event, session->sample_type, &data);
if (al.sym && perf_session__add_hist_entry(session, &al, data.period)) {
@@ -182,10 +185,14 @@ blank: memset(displacement, ' ', sizeof(displacement));
printed = fprintf(fp, "%4lu %5.5s ", pos, displacement);
if (show_percent) {
- double old_percent = (old_count * 100) / pair_session->events_stats.total,
- new_percent = (self->count * 100) / session->events_stats.total;
- double diff = old_percent - new_percent;
+ double old_percent = 0, new_percent = 0, diff;
+
+ if (pair_session->events_stats.total > 0)
+ old_percent = (old_count * 100) / pair_session->events_stats.total;
+ if (session->events_stats.total > 0)
+ new_percent = (self->count * 100) / session->events_stats.total;
+ diff = old_percent - new_percent;
if (verbose)
printed += fprintf(fp, " %3.2f%% %3.2f%%", old_percent, new_percent);
@@ -260,6 +267,12 @@ static const struct option options[] = {
"Don't shorten the pathnames taking into account the cwd"),
OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths,
"Don't shorten the pathnames taking into account the cwd"),
+ OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
+ "only consider symbols in these dsos"),
+ OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
+ "only consider symbols in these comms"),
+ OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
+ "only consider these symbols"),
OPT_END()
};
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 03afac3..9c59534 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -316,14 +316,14 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
if (total_samples)
ret = percent_color_fprintf(fp,
- field_sep ? "%.2f" : " %6.2f%%",
+ symbol_conf.field_sep ? "%.2f" : " %6.2f%%",
(self->count * 100.0) / total_samples);
else
- ret = fprintf(fp, field_sep ? "%lld" : "%12lld ", self->count);
+ ret = fprintf(fp, symbol_conf.field_sep ? "%lld" : "%12lld ", self->count);
if (show_nr_samples) {
- if (field_sep)
- fprintf(fp, "%c%lld", *field_sep, self->count);
+ if (symbol_conf.field_sep)
+ fprintf(fp, "%c%lld", *symbol_conf.field_sep, self->count);
else
fprintf(fp, "%11lld", self->count);
}
@@ -332,7 +332,7 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
if (se->elide)
continue;
- fprintf(fp, "%s", field_sep ?: " ");
+ fprintf(fp, "%s", symbol_conf.field_sep ?: " ");
ret += se->print(fp, self, se->width ? *se->width : 0);
}
@@ -355,28 +355,11 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
return ret;
}
-/*
- *
- */
-
-static void dso__calc_col_width(struct dso *self)
-{
- if (!symbol_conf.col_width_list_str && !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;
-}
-
static void thread__comm_adjust(struct thread *self)
{
char *comm = self->comm;
- if (!symbol_conf.col_width_list_str && !field_sep &&
+ if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
(!symbol_conf.comm_list ||
strlist__has_entry(symbol_conf.comm_list, comm))) {
unsigned int slen = strlen(comm);
@@ -452,16 +435,16 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
fprintf(fp, "# Overhead");
if (show_nr_samples) {
- if (field_sep)
- fprintf(fp, "%cSamples", *field_sep);
+ if (symbol_conf.field_sep)
+ fprintf(fp, "%cSamples", *symbol_conf.field_sep);
else
fputs(" Samples ", fp);
}
list_for_each_entry(se, &hist_entry__sort_list, list) {
if (se->elide)
continue;
- if (field_sep) {
- fprintf(fp, "%c%s", *field_sep, se->header);
+ if (symbol_conf.field_sep) {
+ fprintf(fp, "%c%s", *symbol_conf.field_sep, se->header);
continue;
}
width = strlen(se->header);
@@ -480,7 +463,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
}
fprintf(fp, "\n");
- if (field_sep)
+ if (symbol_conf.field_sep)
goto print_entries;
fprintf(fp, "# ........");
@@ -542,13 +525,8 @@ static int validate_chain(struct ip_callchain *chain, event_t *event)
static int process_sample_event(event_t *event, struct perf_session *session)
{
- struct sample_data data;
- int cpumode;
+ struct sample_data data = { .period = 1, };
struct addr_location al;
- struct thread *thread;
-
- memset(&data, 0, sizeof(data));
- data.period = 1;
event__parse_sample(event, session->sample_type, &data);
@@ -576,39 +554,13 @@ static int process_sample_event(event_t *event, struct perf_session *session)
}
}
- thread = perf_session__findnew(session, data.pid);
- if (thread == NULL) {
- pr_debug("problem processing %d event, skipping it.\n",
+ if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+ fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}
- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
- if (symbol_conf.comm_list &&
- !strlist__has_entry(symbol_conf.comm_list, thread->comm))
- return 0;
-
- cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-
- thread__find_addr_location(thread, session, cpumode,
- MAP__FUNCTION, data.ip, &al, NULL);
- /*
- * 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)))))
- return 0;
-
- if (symbol_conf.sym_list && al.sym &&
- !strlist__has_entry(symbol_conf.sym_list, al.sym->name))
+ if (al.filtered)
return 0;
if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
@@ -834,7 +786,7 @@ static const struct option options[] = {
OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
"width[,width...]",
"don't try to adjust column width, use these fixed values"),
- OPT_STRING('t', "field-separator", &field_sep, "separator",
+ OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
"separator for columns, no spaces will be added between "
"columns '.' is reserved."),
OPT_END()
@@ -877,11 +829,5 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
- if (field_sep && *field_sep == '.') {
- fputs("'.' is the only non valid --field-separator argument\n",
- stderr);
- exit(129);
- }
-
return __cmd_report();
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index cd89b6d..ddc584b 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -948,7 +948,7 @@ static void event__process_sample(const event_t *self,
}
if (event__preprocess_sample(self, session, &al, symbol_filter) < 0 ||
- al.sym == NULL)
+ al.sym == NULL || al.filtered)
return;
syme = symbol__priv(al.sym);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 375fb6d..bf491fd 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 164286a..7707897 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 d61f350..6015152 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 {
--
1.6.2.5
From: Arnaldo Carvalho de Melo <[email protected]>
Further changes will be made and it will then be usable in 'perf diff'
as well.
Cc: Frédéric Weisbecker <[email protected]>
Cc: Mike Galbraith <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Paul Mackerras <[email protected]>
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/builtin-report.c | 114 +++++++++++--------------------------------
tools/perf/util/event.c | 30 +++++++++++-
tools/perf/util/hist.c | 7 +--
tools/perf/util/session.c | 4 +-
tools/perf/util/session.h | 1 -
tools/perf/util/symbol.c | 1 +
tools/perf/util/symbol.h | 5 ++-
7 files changed, 68 insertions(+), 94 deletions(-)
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 9c59534..26f4de6 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -34,9 +34,6 @@
static char const *input_name = "perf.data";
static int force;
-static bool use_callchain;
-
-static int show_nr_samples;
static int show_threads;
static struct perf_read_values show_threads_values;
@@ -44,8 +41,6 @@ static struct perf_read_values show_threads_values;
static char default_pretty_printing_style[] = "normal";
static char *pretty_printing_style = default_pretty_printing_style;
-static int exclude_other = 1;
-
static char callchain_default_opt[] = "fractal,0.5";
static size_t
@@ -305,23 +300,22 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
}
static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
- struct perf_session *session,
- u64 total_samples)
+ struct perf_session *session)
{
struct sort_entry *se;
size_t ret;
- if (exclude_other && !self->parent)
+ if (symbol_conf.exclude_other && !self->parent)
return 0;
- if (total_samples)
+ if (session->events_stats.total)
ret = percent_color_fprintf(fp,
symbol_conf.field_sep ? "%.2f" : " %6.2f%%",
- (self->count * 100.0) / total_samples);
+ (self->count * 100.0) / session->events_stats.total);
else
ret = fprintf(fp, symbol_conf.field_sep ? "%lld" : "%12lld ", self->count);
- if (show_nr_samples) {
+ if (symbol_conf.show_nr_samples) {
if (symbol_conf.field_sep)
fprintf(fp, "%c%lld", *symbol_conf.field_sep, self->count);
else
@@ -338,7 +332,7 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
ret += fprintf(fp, "\n");
- if (session->use_callchain) {
+ if (symbol_conf.use_callchain) {
int left_margin = 0;
if (sort__first_dimension == SORT_COMM) {
@@ -348,41 +342,13 @@ static size_t hist_entry__fprintf(FILE *fp, struct hist_entry *self,
left_margin -= thread__comm_len(self->thread);
}
- hist_entry_callchain__fprintf(fp, self, total_samples,
+ hist_entry_callchain__fprintf(fp, self, session->events_stats.total,
left_margin);
}
return ret;
}
-static void thread__comm_adjust(struct thread *self)
-{
- char *comm = self->comm;
-
- if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
- (!symbol_conf.comm_list ||
- strlist__has_entry(symbol_conf.comm_list, comm))) {
- unsigned int slen = strlen(comm);
-
- if (slen > comms__col_width) {
- comms__col_width = slen;
- threads__col_width = slen + 6;
- }
- }
-}
-
-static int thread__set_comm_adjust(struct thread *self, const char *comm)
-{
- int ret = thread__set_comm(self, comm);
-
- if (ret)
- return ret;
-
- thread__comm_adjust(self);
-
- return 0;
-}
-
/*
* collect histogram counts
*/
@@ -395,7 +361,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
bool hit;
struct hist_entry *he;
- if ((sort__has_parent || self->use_callchain) && chain)
+ if ((sort__has_parent || symbol_conf.use_callchain) && chain)
syms = perf_session__resolve_callchain(self, al->thread,
chain, &parent);
he = __perf_session__add_hist_entry(self, al, parent, count, &hit);
@@ -405,7 +371,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
if (hit)
he->count += count;
- if (self->use_callchain) {
+ if (symbol_conf.use_callchain) {
if (!hit)
callchain_init(&he->callchain);
append_chain(&he->callchain, chain, syms);
@@ -415,8 +381,7 @@ static int perf_session__add_hist_entry(struct perf_session *self,
return 0;
}
-static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
- u64 total_samples, FILE *fp)
+static size_t perf_session__fprintf_hists(struct perf_session *self, FILE *fp)
{
struct hist_entry *pos;
struct sort_entry *se;
@@ -424,17 +389,14 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
size_t ret = 0;
unsigned int width;
char *col_width = symbol_conf.col_width_list_str;
- int raw_printing_style;
-
- raw_printing_style = !strcmp(pretty_printing_style, "raw");
init_rem_hits();
- fprintf(fp, "# Samples: %Ld\n", (u64)total_samples);
+ fprintf(fp, "# Samples: %ld\n", self->events_stats.total);
fprintf(fp, "#\n");
fprintf(fp, "# Overhead");
- if (show_nr_samples) {
+ if (symbol_conf.show_nr_samples) {
if (symbol_conf.field_sep)
fprintf(fp, "%cSamples", *symbol_conf.field_sep);
else
@@ -467,7 +429,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
goto print_entries;
fprintf(fp, "# ........");
- if (show_nr_samples)
+ if (symbol_conf.show_nr_samples)
fprintf(fp, " ..........");
list_for_each_entry(se, &hist_entry__sort_list, list) {
unsigned int i;
@@ -490,7 +452,7 @@ static size_t perf_session__fprintf_hist_entries(struct perf_session *self,
print_entries:
for (nd = rb_first(&self->hists); nd; nd = rb_next(nd)) {
pos = rb_entry(nd, struct hist_entry, rb_node);
- ret += hist_entry__fprintf(fp, pos, self, total_samples);
+ ret += hist_entry__fprintf(fp, pos, self);
}
if (sort_order == default_sort_order &&
@@ -503,10 +465,6 @@ print_entries:
free(rem_sq_bracket);
- if (show_threads)
- perf_read_values_display(fp, &show_threads_values,
- raw_printing_style);
-
return ret;
}
@@ -572,21 +530,6 @@ static int process_sample_event(event_t *event, struct perf_session *session)
return 0;
}
-static int process_comm_event(event_t *event, struct perf_session *session)
-{
- struct thread *thread = perf_session__findnew(session, event->comm.pid);
-
- dump_printf(": %s:%d\n", event->comm.comm, event->comm.pid);
-
- if (thread == NULL ||
- thread__set_comm_adjust(thread, event->comm.comm)) {
- dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
- return -1;
- }
-
- return 0;
-}
-
static int process_read_event(event_t *event, struct perf_session *session __used)
{
struct perf_event_attr *attr;
@@ -619,14 +562,14 @@ static int sample_type_check(struct perf_session *session)
" perf record without -g?\n");
return -1;
}
- if (session->use_callchain) {
+ if (symbol_conf.use_callchain) {
fprintf(stderr, "selected -g but no callchain data."
" Did you call perf record without"
" -g?\n");
return -1;
}
- } else if (callchain_param.mode != CHAIN_NONE && !session->use_callchain) {
- session->use_callchain = true;
+ } else if (callchain_param.mode != CHAIN_NONE && !symbol_conf.use_callchain) {
+ symbol_conf.use_callchain = true;
if (register_callchain_param(&callchain_param) < 0) {
fprintf(stderr, "Can't register callchain"
" params\n");
@@ -640,7 +583,7 @@ static int sample_type_check(struct perf_session *session)
static struct perf_event_ops event_ops = {
.process_sample_event = process_sample_event,
.process_mmap_event = event__process_mmap,
- .process_comm_event = process_comm_event,
+ .process_comm_event = event__process_mmap,
.process_exit_event = event__process_task,
.process_fork_event = event__process_task,
.process_lost_event = event__process_lost,
@@ -658,8 +601,6 @@ static int __cmd_report(void)
if (session == NULL)
return -ENOMEM;
- session->use_callchain = use_callchain;
-
if (show_threads)
perf_read_values_init(&show_threads_values);
@@ -680,10 +621,13 @@ static int __cmd_report(void)
perf_session__collapse_resort(session);
perf_session__output_resort(session, session->events_stats.total);
- perf_session__fprintf_hist_entries(session, session->events_stats.total, stdout);
-
- if (show_threads)
+ perf_session__fprintf_hists(session, stdout);
+ if (show_threads) {
+ bool raw_printing_style = !strcmp(pretty_printing_style, "raw");
+ perf_read_values_display(stdout, &show_threads_values,
+ raw_printing_style);
perf_read_values_destroy(&show_threads_values);
+ }
out_delete:
perf_session__delete(session);
return ret;
@@ -696,7 +640,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
char *tok;
char *endptr;
- use_callchain = true;
+ symbol_conf.use_callchain = true;
if (!arg)
return 0;
@@ -717,7 +661,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
else if (!strncmp(tok, "none", strlen(arg))) {
callchain_param.mode = CHAIN_NONE;
- use_callchain = true;
+ symbol_conf.use_callchain = true;
return 0;
}
@@ -760,7 +704,7 @@ static const struct option options[] = {
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
"load module symbols - WARNING: use only with -k and LIVE kernel"),
- OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples,
+ OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
"Show a column with the number of samples"),
OPT_BOOLEAN('T', "threads", &show_threads,
"Show per-thread event counters"),
@@ -772,7 +716,7 @@ static const struct option options[] = {
"Don't shorten the pathnames taking into account the cwd"),
OPT_STRING('p', "parent", &parent_pattern, "regex",
"regex filter to identify parent, see: '--sort parent'"),
- OPT_BOOLEAN('x', "exclude-other", &exclude_other,
+ OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
"Only display entries with parent-match"),
OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent",
"Display callchains using output_type and min percent threshold. "
@@ -817,7 +761,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
sort_dimension__add("parent");
sort_parent.elide = 1;
} else
- exclude_other = 0;
+ symbol_conf.exclude_other = false;
/*
* Any (unrecognized) arguments left?
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index bf491fd..bb0fd6d 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -189,13 +189,41 @@ void event__synthesize_threads(int (*process)(event_t *event,
closedir(proc);
}
+static void thread__comm_adjust(struct thread *self)
+{
+ char *comm = self->comm;
+
+ if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
+ (!symbol_conf.comm_list ||
+ strlist__has_entry(symbol_conf.comm_list, comm))) {
+ unsigned int slen = strlen(comm);
+
+ if (slen > comms__col_width) {
+ comms__col_width = slen;
+ threads__col_width = slen + 6;
+ }
+ }
+}
+
+static int thread__set_comm_adjust(struct thread *self, const char *comm)
+{
+ int ret = thread__set_comm(self, comm);
+
+ if (ret)
+ return ret;
+
+ thread__comm_adjust(self);
+
+ return 0;
+}
+
int event__process_comm(event_t *self, struct perf_session *session)
{
struct thread *thread = perf_session__findnew(session, self->comm.pid);
dump_printf(": %s:%d\n", self->comm.comm, self->comm.pid);
- if (thread == NULL || thread__set_comm(thread, self->comm.comm)) {
+ if (thread == NULL || thread__set_comm_adjust(thread, self->comm.comm)) {
dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n");
return -1;
}
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index b9828fc..d9a5a19 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -156,8 +156,7 @@ void perf_session__collapse_resort(struct perf_session *self)
* reverse the map, sort on count.
*/
-static void perf_session__insert_output_hist_entry(struct perf_session *self,
- struct rb_root *root,
+static void perf_session__insert_output_hist_entry(struct rb_root *root,
struct hist_entry *he,
u64 min_callchain_hits)
{
@@ -165,7 +164,7 @@ static void perf_session__insert_output_hist_entry(struct perf_session *self,
struct rb_node *parent = NULL;
struct hist_entry *iter;
- if (self->use_callchain)
+ if (symbol_conf.use_callchain)
callchain_param.sort(&he->sorted_chain, &he->callchain,
min_callchain_hits, &callchain_param);
@@ -201,7 +200,7 @@ void perf_session__output_resort(struct perf_session *self, u64 total_samples)
next = rb_next(&n->rb_node);
rb_erase(&n->rb_node, &self->hists);
- perf_session__insert_output_hist_entry(self, &tmp, n,
+ perf_session__insert_output_hist_entry(&tmp, n,
min_callchain_hits);
}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index bceaa09..ce3a6c8 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -108,7 +108,7 @@ struct symbol **perf_session__resolve_callchain(struct perf_session *self,
struct symbol **syms = NULL;
unsigned int i;
- if (self->use_callchain) {
+ if (symbol_conf.use_callchain) {
syms = calloc(chain->nr, sizeof(*syms));
if (!syms) {
fprintf(stderr, "Can't allocate memory for symbols\n");
@@ -140,7 +140,7 @@ struct symbol **perf_session__resolve_callchain(struct perf_session *self,
if (sort__has_parent && !*parent &&
symbol__match_parent_regex(al.sym))
*parent = al.sym;
- if (!self->use_callchain)
+ if (!symbol_conf.use_callchain)
break;
syms[i] = al.sym;
}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index faf18a8..32eaa1b 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -25,7 +25,6 @@ struct perf_session {
int fd;
int cwdlen;
char *cwd;
- bool use_callchain;
char filename[0];
};
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 7707897..ab92763 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -38,6 +38,7 @@ static int vmlinux_path__nr_entries;
static char **vmlinux_path;
struct symbol_conf symbol_conf = {
+ .exclude_other = true,
.use_modules = true,
.try_vmlinux_path = true,
};
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6015152..8aded23 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -55,7 +55,10 @@ struct symbol_conf {
unsigned short priv_size;
bool try_vmlinux_path,
use_modules,
- sort_by_name;
+ sort_by_name,
+ show_nr_samples,
+ use_callchain,
+ exclude_other;
const char *vmlinux_name,
*field_sep;
char *dso_list_str,
--
1.6.2.5