Commit 8b7cdd08 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'perf/core' of...

Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/urgent
parents d1090281 43adec95
perf-evlist(1)
==============
NAME
----
perf-evlist - List the event names in a perf.data file
SYNOPSIS
--------
[verse]
'perf evlist <options>'
DESCRIPTION
-----------
This command displays the names of events sampled in a perf.data file.
OPTIONS
-------
-i::
--input=::
Input file name. (default: perf.data)
SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-list[1],
linkperf:perf-report[1]
...@@ -112,6 +112,28 @@ OPTIONS ...@@ -112,6 +112,28 @@ OPTIONS
--debug-mode:: --debug-mode::
Do various checks like samples ordering and lost events. Do various checks like samples ordering and lost events.
-f::
--fields
Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace, sym. Field
list must be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies.
e.g., -f sw:comm,tid,time,sym and -f trace:time,cpu,trace
-k::
--vmlinux=<file>::
vmlinux pathname
--kallsyms=<file>::
kallsyms pathname
--symfs=<directory>::
Look for files with symbols relative to this directory.
-G::
--hide-call-graph::
When printing symbols do not display call chain.
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-record[1], linkperf:perf-script-perl[1], linkperf:perf-record[1], linkperf:perf-script-perl[1],
......
...@@ -338,6 +338,7 @@ endif ...@@ -338,6 +338,7 @@ endif
BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
BUILTIN_OBJS += $(OUTPUT)builtin-diff.o BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
BUILTIN_OBJS += $(OUTPUT)builtin-help.o BUILTIN_OBJS += $(OUTPUT)builtin-help.o
BUILTIN_OBJS += $(OUTPUT)builtin-sched.o BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
......
/*
* Builtin evlist command: Show the list of event selectors present
* in a perf.data file.
*/
#include "builtin.h"
#include "util/util.h"
#include <linux/list.h>
#include "perf.h"
#include "util/evlist.h"
#include "util/evsel.h"
#include "util/parse-events.h"
#include "util/parse-options.h"
#include "util/session.h"
static char const *input_name = "perf.data";
static int __cmd_evlist(void)
{
struct perf_session *session;
struct perf_evsel *pos;
session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
if (session == NULL)
return -ENOMEM;
list_for_each_entry(pos, &session->evlist->entries, node)
printf("%s\n", event_name(pos));
perf_session__delete(session);
return 0;
}
static const char * const evlist_usage[] = {
"perf evlist [<options>]",
NULL
};
static const struct option options[] = {
OPT_STRING('i', "input", &input_name, "file",
"input file name"),
OPT_END()
};
int cmd_evlist(int argc, const char **argv, const char *prefix __used)
{
argc = parse_options(argc, argv, options, evlist_usage, 0);
if (argc)
usage_with_options(evlist_usage, options);
return __cmd_evlist();
}
This diff is collapsed.
...@@ -333,6 +333,12 @@ static int run_perf_stat(int argc __used, const char **argv) ...@@ -333,6 +333,12 @@ static int run_perf_stat(int argc __used, const char **argv)
} }
} }
if (perf_evlist__set_filters(evsel_list)) {
error("failed to set filter with %d (%s)\n", errno,
strerror(errno));
return -1;
}
/* /*
* Enable counters and exec the command: * Enable counters and exec the command:
*/ */
...@@ -634,6 +640,8 @@ static const struct option options[] = { ...@@ -634,6 +640,8 @@ static const struct option options[] = {
OPT_CALLBACK('e', "event", &evsel_list, "event", OPT_CALLBACK('e', "event", &evsel_list, "event",
"event selector. use 'perf list' to list available events", "event selector. use 'perf list' to list available events",
parse_events), parse_events),
OPT_CALLBACK(0, "filter", &evsel_list, "filter",
"event filter", parse_filter),
OPT_BOOLEAN('i', "no-inherit", &no_inherit, OPT_BOOLEAN('i', "no-inherit", &no_inherit,
"child tasks do not inherit counters"), "child tasks do not inherit counters"),
OPT_INTEGER('p', "pid", &target_pid, OPT_INTEGER('p', "pid", &target_pid,
......
...@@ -152,7 +152,7 @@ static int parse_source(struct sym_entry *syme) ...@@ -152,7 +152,7 @@ static int parse_source(struct sym_entry *syme)
/* /*
* We can't annotate with just /proc/kallsyms * We can't annotate with just /proc/kallsyms
*/ */
if (map->dso->origin == DSO__ORIG_KERNEL) { if (map->dso->symtab_type == SYMTAB__KALLSYMS) {
pr_err("Can't annotate %s: No vmlinux file was found in the " pr_err("Can't annotate %s: No vmlinux file was found in the "
"path\n", sym->name); "path\n", sym->name);
sleep(1); sleep(1);
...@@ -515,24 +515,25 @@ static void handle_keypress(struct perf_session *session, int c) ...@@ -515,24 +515,25 @@ static void handle_keypress(struct perf_session *session, int c)
break; break;
case 'E': case 'E':
if (top.evlist->nr_entries > 1) { if (top.evlist->nr_entries > 1) {
int counter;
fprintf(stderr, "\nAvailable events:"); fprintf(stderr, "\nAvailable events:");
list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
fprintf(stderr, "\n\t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel)); fprintf(stderr, "\n\t%d %s", top.sym_evsel->idx, event_name(top.sym_evsel));
prompt_integer(&top.sym_counter, "Enter details event counter"); prompt_integer(&counter, "Enter details event counter");
if (top.sym_counter >= top.evlist->nr_entries) { if (counter >= top.evlist->nr_entries) {
top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node); top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
top.sym_counter = 0;
fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top.sym_evsel)); fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(top.sym_evsel));
sleep(1); sleep(1);
break; break;
} }
list_for_each_entry(top.sym_evsel, &top.evlist->entries, node) list_for_each_entry(top.sym_evsel, &top.evlist->entries, node)
if (top.sym_evsel->idx == top.sym_counter) if (top.sym_evsel->idx == counter)
break; break;
} else top.sym_counter = 0; } else
top.sym_evsel = list_entry(top.evlist->entries.next, struct perf_evsel, node);
break; break;
case 'f': case 'f':
prompt_integer(&top.count_filter, "Enter display event count filter"); prompt_integer(&top.count_filter, "Enter display event count filter");
...@@ -675,7 +676,7 @@ static int symbol_filter(struct map *map, struct symbol *sym) ...@@ -675,7 +676,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)
for (i = 0; skip_symbols[i]; i++) { for (i = 0; skip_symbols[i]; i++) {
if (!strcmp(skip_symbols[i], name)) { if (!strcmp(skip_symbols[i], name)) {
syme->skip = 1; sym->ignore = true;
break; break;
} }
} }
...@@ -768,7 +769,7 @@ static void perf_event__process_sample(const union perf_event *event, ...@@ -768,7 +769,7 @@ static void perf_event__process_sample(const union perf_event *event,
struct symbol *sym = sym_entry__symbol(top.sym_filter_entry); struct symbol *sym = sym_entry__symbol(top.sym_filter_entry);
pr_err("Can't annotate %s", sym->name); pr_err("Can't annotate %s", sym->name);
if (top.sym_filter_entry->map->dso->origin == DSO__ORIG_KERNEL) { if (top.sym_filter_entry->map->dso->symtab_type == SYMTAB__KALLSYMS) {
pr_err(": No vmlinux file was found in the path:\n"); pr_err(": No vmlinux file was found in the path:\n");
machine__fprintf_vmlinux_path(machine, stderr); machine__fprintf_vmlinux_path(machine, stderr);
} else } else
...@@ -778,10 +779,9 @@ static void perf_event__process_sample(const union perf_event *event, ...@@ -778,10 +779,9 @@ static void perf_event__process_sample(const union perf_event *event,
} }
syme = symbol__priv(al.sym); syme = symbol__priv(al.sym);
if (!syme->skip) { if (!al.sym->ignore) {
struct perf_evsel *evsel; struct perf_evsel *evsel;
syme->origin = origin;
evsel = perf_evlist__id2evsel(top.evlist, sample->id); evsel = perf_evlist__id2evsel(top.evlist, sample->id);
assert(evsel != NULL); assert(evsel != NULL);
syme->count[evsel->idx]++; syme->count[evsel->idx]++;
......
...@@ -19,6 +19,7 @@ extern int cmd_bench(int argc, const char **argv, const char *prefix); ...@@ -19,6 +19,7 @@ extern int cmd_bench(int argc, const char **argv, const char *prefix);
extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix); extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix);
extern int cmd_buildid_list(int argc, const char **argv, const char *prefix); extern int cmd_buildid_list(int argc, const char **argv, const char *prefix);
extern int cmd_diff(int argc, const char **argv, const char *prefix); extern int cmd_diff(int argc, const char **argv, const char *prefix);
extern int cmd_evlist(int argc, const char **argv, const char *prefix);
extern int cmd_help(int argc, const char **argv, const char *prefix); extern int cmd_help(int argc, const char **argv, const char *prefix);
extern int cmd_sched(int argc, const char **argv, const char *prefix); extern int cmd_sched(int argc, const char **argv, const char *prefix);
extern int cmd_list(int argc, const char **argv, const char *prefix); extern int cmd_list(int argc, const char **argv, const char *prefix);
......
...@@ -8,6 +8,7 @@ perf-bench mainporcelain common ...@@ -8,6 +8,7 @@ perf-bench mainporcelain common
perf-buildid-cache mainporcelain common perf-buildid-cache mainporcelain common
perf-buildid-list mainporcelain common perf-buildid-list mainporcelain common
perf-diff mainporcelain common perf-diff mainporcelain common
perf-evlist mainporcelain common
perf-inject mainporcelain common perf-inject mainporcelain common
perf-list mainporcelain common perf-list mainporcelain common
perf-sched mainporcelain common perf-sched mainporcelain common
......
...@@ -313,6 +313,7 @@ static void handle_internal_command(int argc, const char **argv) ...@@ -313,6 +313,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "buildid-cache", cmd_buildid_cache, 0 }, { "buildid-cache", cmd_buildid_cache, 0 },
{ "buildid-list", cmd_buildid_list, 0 }, { "buildid-list", cmd_buildid_list, 0 },
{ "diff", cmd_diff, 0 }, { "diff", cmd_diff, 0 },
{ "evlist", cmd_evlist, 0 },
{ "help", cmd_help, 0 }, { "help", cmd_help, 0 },
{ "list", cmd_list, 0 }, { "list", cmd_list, 0 },
{ "record", cmd_record, 0 }, { "record", cmd_record, 0 },
......
...@@ -294,7 +294,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) ...@@ -294,7 +294,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
free_filename = false; free_filename = false;
} }
if (dso->origin == DSO__ORIG_KERNEL) { if (dso->symtab_type == SYMTAB__KALLSYMS) {
char bf[BUILD_ID_SIZE * 2 + 16] = " with build id "; char bf[BUILD_ID_SIZE * 2 + 16] = " with build id ";
char *build_id_msg = NULL; char *build_id_msg = NULL;
......
...@@ -263,6 +263,28 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result) ...@@ -263,6 +263,28 @@ static char *event_cache_name(u8 cache_type, u8 cache_op, u8 cache_result)
return name; return name;
} }
const char *event_type(int type)
{
switch (type) {
case PERF_TYPE_HARDWARE:
return "hardware";
case PERF_TYPE_SOFTWARE:
return "software";
case PERF_TYPE_TRACEPOINT:
return "tracepoint";
case PERF_TYPE_HW_CACHE:
return "hardware-cache";
default:
break;
}
return "unknown";
}
const char *event_name(struct perf_evsel *evsel) const char *event_name(struct perf_evsel *evsel)
{ {
u64 config = evsel->attr.config; u64 config = evsel->attr.config;
......
...@@ -20,6 +20,7 @@ struct tracepoint_path { ...@@ -20,6 +20,7 @@ struct tracepoint_path {
extern struct tracepoint_path *tracepoint_id_to_path(u64 config); extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
extern bool have_tracepoints(struct list_head *evlist); extern bool have_tracepoints(struct list_head *evlist);
const char *event_type(int type);
const char *event_name(struct perf_evsel *event); const char *event_name(struct perf_evsel *event);
extern const char *__event_name(int type, u64 config); extern const char *__event_name(int type, u64 config);
......
...@@ -245,9 +245,10 @@ static inline struct event *find_cache_event(int type) ...@@ -245,9 +245,10 @@ static inline struct event *find_cache_event(int type)
return event; return event;
} }
static void perl_process_event(int cpu, void *data, static void perl_process_event(union perf_event *pevent __unused,
int size __unused, struct perf_sample *sample,
unsigned long long nsecs, char *comm) struct perf_session *session __unused,
struct thread *thread)
{ {
struct format_field *field; struct format_field *field;
static char handler[256]; static char handler[256];
...@@ -256,6 +257,10 @@ static void perl_process_event(int cpu, void *data, ...@@ -256,6 +257,10 @@ static void perl_process_event(int cpu, void *data,
struct event *event; struct event *event;
int type; int type;
int pid; int pid;
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
char *comm = thread->comm;
dSP; dSP;
......
...@@ -204,9 +204,10 @@ static inline struct event *find_cache_event(int type) ...@@ -204,9 +204,10 @@ static inline struct event *find_cache_event(int type)
return event; return event;
} }
static void python_process_event(int cpu, void *data, static void python_process_event(union perf_event *pevent __unused,
int size __unused, struct perf_sample *sample,
unsigned long long nsecs, char *comm) struct perf_session *session __unused,
struct thread *thread)
{ {
PyObject *handler, *retval, *context, *t, *obj, *dict = NULL; PyObject *handler, *retval, *context, *t, *obj, *dict = NULL;
static char handler_name[256]; static char handler_name[256];
...@@ -217,6 +218,10 @@ static void python_process_event(int cpu, void *data, ...@@ -217,6 +218,10 @@ static void python_process_event(int cpu, void *data,
unsigned n = 0; unsigned n = 0;
int type; int type;
int pid; int pid;
int cpu = sample->cpu;
void *data = sample->raw_data;
unsigned long long nsecs = sample->time;
char *comm = thread->comm;
t = PyTuple_New(MAX_FIELDS); t = PyTuple_New(MAX_FIELDS);
if (!t) if (!t)
......
...@@ -1134,3 +1134,64 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) ...@@ -1134,3 +1134,64 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp)
return ret; return ret;
} }
void perf_session__print_symbols(union perf_event *event,
struct perf_sample *sample,
struct perf_session *session)
{
struct addr_location al;
const char *symname, *dsoname;
struct callchain_cursor *cursor = &session->callchain_cursor;
struct callchain_cursor_node *node;
if (perf_event__preprocess_sample(event, session, &al, sample,
NULL) < 0) {
error("problem processing %d event, skipping it.\n",
event->header.type);
return;
}
if (symbol_conf.use_callchain && sample->callchain) {
if (perf_session__resolve_callchain(session, al.thread,
sample->callchain, NULL) != 0) {
if (verbose)
error("Failed to resolve callchain. Skipping\n");
return;
}
callchain_cursor_commit(cursor);
while (1) {
node = callchain_cursor_current(cursor);
if (!node)
break;
if (node->sym && node->sym->name)
symname = node->sym->name;
else
symname = "";
if (node->map && node->map->dso && node->map->dso->name)
dsoname = node->map->dso->name;
else
dsoname = "";
printf("\t%16" PRIx64 " %s (%s)\n", node->ip, symname, dsoname);
callchain_cursor_advance(cursor);
}
} else {
if (al.sym && al.sym->name)
symname = al.sym->name;
else
symname = "";
if (al.map && al.map->dso && al.map->dso->name)
dsoname = al.map->dso->name;
else
dsoname = "";
printf("%16" PRIx64 " %s (%s)", al.addr, symname, dsoname);
}
}
...@@ -159,4 +159,8 @@ static inline int perf_session__parse_sample(struct perf_session *session, ...@@ -159,4 +159,8 @@ static inline int perf_session__parse_sample(struct perf_session *session,
session->sample_id_all, sample); session->sample_id_all, sample);
} }
void perf_session__print_symbols(union perf_event *event,
struct perf_sample *sample,
struct perf_session *session);
#endif /* __PERF_SESSION_H */ #endif /* __PERF_SESSION_H */
...@@ -207,7 +207,7 @@ struct dso *dso__new(const char *name) ...@@ -207,7 +207,7 @@ struct dso *dso__new(const char *name)
dso__set_short_name(self, self->name); dso__set_short_name(self, self->name);
for (i = 0; i < MAP__NR_TYPES; ++i) for (i = 0; i < MAP__NR_TYPES; ++i)
self->symbols[i] = self->symbol_names[i] = RB_ROOT; self->symbols[i] = self->symbol_names[i] = RB_ROOT;
self->origin = DSO__ORIG_NOT_FOUND; self->symtab_type = SYMTAB__NOT_FOUND;
self->loaded = 0; self->loaded = 0;
self->sorted_by_name = 0; self->sorted_by_name = 0;
self->has_build_id = 0; self->has_build_id = 0;
...@@ -680,9 +680,9 @@ int dso__load_kallsyms(struct dso *self, const char *filename, ...@@ -680,9 +680,9 @@ int dso__load_kallsyms(struct dso *self, const char *filename,
return -1; return -1;
if (self->kernel == DSO_TYPE_GUEST_KERNEL) if (self->kernel == DSO_TYPE_GUEST_KERNEL)
self->origin = DSO__ORIG_GUEST_KERNEL; self->symtab_type = SYMTAB__GUEST_KALLSYMS;
else else
self->origin = DSO__ORIG_KERNEL; self->symtab_type = SYMTAB__KALLSYMS;
return dso__split_kallsyms(self, map, filter); return dso__split_kallsyms(self, map, filter);
} }
...@@ -1204,7 +1204,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, ...@@ -1204,7 +1204,7 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
} }
curr_map->map_ip = identity__map_ip; curr_map->map_ip = identity__map_ip;
curr_map->unmap_ip = identity__map_ip; curr_map->unmap_ip = identity__map_ip;
curr_dso->origin = self->origin; curr_dso->symtab_type = self->symtab_type;
map_groups__insert(kmap->kmaps, curr_map); map_groups__insert(kmap->kmaps, curr_map);
dsos__add(&self->node, curr_dso); dsos__add(&self->node, curr_dso);
dso__set_loaded(curr_dso, map->type); dso__set_loaded(curr_dso, map->type);
...@@ -1430,21 +1430,21 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size) ...@@ -1430,21 +1430,21 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
char dso__symtab_origin(const struct dso *self) char dso__symtab_origin(const struct dso *self)
{ {
static const char origin[] = { static const char origin[] = {
[DSO__ORIG_KERNEL] = 'k', [SYMTAB__KALLSYMS] = 'k',
[DSO__ORIG_JAVA_JIT] = 'j', [SYMTAB__JAVA_JIT] = 'j',
[DSO__ORIG_BUILD_ID_CACHE] = 'B', [SYMTAB__BUILD_ID_CACHE] = 'B',
[DSO__ORIG_FEDORA] = 'f', [SYMTAB__FEDORA_DEBUGINFO] = 'f',
[DSO__ORIG_UBUNTU] = 'u', [SYMTAB__UBUNTU_DEBUGINFO] = 'u',
[DSO__ORIG_BUILDID] = 'b', [SYMTAB__BUILDID_DEBUGINFO] = 'b',
[DSO__ORIG_DSO] = 'd', [SYMTAB__SYSTEM_PATH_DSO] = 'd',
[DSO__ORIG_KMODULE] = 'K', [SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
[DSO__ORIG_GUEST_KERNEL] = 'g', [SYMTAB__GUEST_KALLSYMS] = 'g',
[DSO__ORIG_GUEST_KMODULE] = 'G', [SYMTAB__GUEST_KMODULE] = 'G',
}; };
if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) if (self == NULL || self->symtab_type == SYMTAB__NOT_FOUND)
return '!'; return '!';
return origin[self->origin]; return origin[self->symtab_type];
} }
int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
...@@ -1477,8 +1477,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) ...@@ -1477,8 +1477,8 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
if (strncmp(self->name, "/tmp/perf-", 10) == 0) { if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
ret = dso__load_perf_map(self, map, filter); ret = dso__load_perf_map(self, map, filter);
self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : self->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
DSO__ORIG_NOT_FOUND; SYMTAB__NOT_FOUND;
return ret; return ret;
} }
...@@ -1486,26 +1486,26 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) ...@@ -1486,26 +1486,26 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
* On the first pass, only load images if they have a full symtab. * On the first pass, only load images if they have a full symtab.
* Failing that, do a second pass where we accept .dynsym also * Failing that, do a second pass where we accept .dynsym also
*/ */
for (self->origin = DSO__ORIG_BUILD_ID_CACHE, want_symtab = 1; for (self->symtab_type = SYMTAB__BUILD_ID_CACHE, want_symtab = 1;
self->origin != DSO__ORIG_NOT_FOUND; self->symtab_type != SYMTAB__NOT_FOUND;
self->origin++) { self->symtab_type++) {
switch (self->origin) { switch (self->symtab_type) {
case DSO__ORIG_BUILD_ID_CACHE: case SYMTAB__BUILD_ID_CACHE:
/* skip the locally configured cache if a symfs is given */ /* skip the locally configured cache if a symfs is given */
if (symbol_conf.symfs[0] || if (symbol_conf.symfs[0] ||
(dso__build_id_filename(self, name, size) == NULL)) { (dso__build_id_filename(self, name, size) == NULL)) {
continue; continue;
} }
break; break;
case DSO__ORIG_FEDORA: case SYMTAB__FEDORA_DEBUGINFO:
snprintf(name, size, "%s/usr/lib/debug%s.debug", snprintf(name, size, "%s/usr/lib/debug%s.debug",
symbol_conf.symfs, self->long_name); symbol_conf.symfs, self->long_name);
break; break;
case DSO__ORIG_UBUNTU: case SYMTAB__UBUNTU_DEBUGINFO:
snprintf(name, size, "%s/usr/lib/debug%s", snprintf(name, size, "%s/usr/lib/debug%s",
symbol_conf.symfs, self->long_name); symbol_conf.symfs, self->long_name);
break; break;
case DSO__ORIG_BUILDID: { case SYMTAB__BUILDID_DEBUGINFO: {
char build_id_hex[BUILD_ID_SIZE * 2 + 1]; char build_id_hex[BUILD_ID_SIZE * 2 + 1];
if (!self->has_build_id) if (!self->has_build_id)
...@@ -1519,11 +1519,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) ...@@ -1519,11 +1519,11 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
symbol_conf.symfs, build_id_hex, build_id_hex + 2); symbol_conf.symfs, build_id_hex, build_id_hex + 2);
} }
break; break;
case DSO__ORIG_DSO: case SYMTAB__SYSTEM_PATH_DSO:
snprintf(name, size, "%s%s", snprintf(name, size, "%s%s",
symbol_conf.symfs, self->long_name); symbol_conf.symfs, self->long_name);
break; break;
case DSO__ORIG_GUEST_KMODULE: case SYMTAB__GUEST_KMODULE:
if (map->groups && machine) if (map->groups && machine)
root_dir = machine->root_dir; root_dir = machine->root_dir;
else else
...@@ -1532,7 +1532,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) ...@@ -1532,7 +1532,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
root_dir, self->long_name); root_dir, self->long_name);
break; break;
case DSO__ORIG_KMODULE: case SYMTAB__SYSTEM_PATH_KMODULE:
snprintf(name, size, "%s%s", symbol_conf.symfs, snprintf(name, size, "%s%s", symbol_conf.symfs,
self->long_name); self->long_name);
break; break;
...@@ -1544,7 +1544,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter) ...@@ -1544,7 +1544,7 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
*/ */
if (want_symtab) { if (want_symtab) {
want_symtab = 0; want_symtab = 0;
self->origin = DSO__ORIG_BUILD_ID_CACHE; self->symtab_type = SYMTAB__BUILD_ID_CACHE;
} else } else
continue; continue;
} }
...@@ -1757,9 +1757,9 @@ struct map *machine__new_module(struct machine *self, u64 start, ...@@ -1757,9 +1757,9 @@ struct map *machine__new_module(struct machine *self, u64 start,
return NULL; return NULL;
if (machine__is_host(self)) if (machine__is_host(self))
dso->origin = DSO__ORIG_KMODULE; dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
else else
dso->origin = DSO__ORIG_GUEST_KMODULE; dso->symtab_type = SYMTAB__GUEST_KMODULE;
map_groups__insert(&self->kmaps, map); map_groups__insert(&self->kmaps, map);
return map; return map;
} }
......
...@@ -48,12 +48,17 @@ char *strxfrchar(char *s, char from, char to); ...@@ -48,12 +48,17 @@ char *strxfrchar(char *s, char from, char to);
#define BUILD_ID_SIZE 20 #define BUILD_ID_SIZE 20
/** struct symbol - symtab entry
*
* @ignore - resolvable but tools ignore it (e.g. idle routines)
*/
struct symbol { struct symbol {
struct rb_node rb_node; struct rb_node rb_node;
u64 start; u64 start;
u64 end; u64 end;
u16 namelen; u16 namelen;
u8 binding; u8 binding;
bool ignore;
char name[0]; char name[0];
}; };
...@@ -137,7 +142,7 @@ struct dso { ...@@ -137,7 +142,7 @@ struct dso {
u8 annotate_warned:1; u8 annotate_warned:1;
u8 sname_alloc:1; u8 sname_alloc:1;
u8 lname_alloc:1; u8 lname_alloc:1;
unsigned char origin; unsigned char symtab_type;
u8 sorted_by_name; u8 sorted_by_name;
u8 loaded; u8 loaded;
u8 build_id[BUILD_ID_SIZE]; u8 build_id[BUILD_ID_SIZE];
...@@ -188,18 +193,18 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp); ...@@ -188,18 +193,18 @@ size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp); size_t dso__fprintf_symbols_by_name(struct dso *self, enum map_type type, FILE *fp);
size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp); size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
enum dso_origin { enum symtab_type {
DSO__ORIG_KERNEL = 0, SYMTAB__KALLSYMS = 0,
DSO__ORIG_GUEST_KERNEL, SYMTAB__GUEST_KALLSYMS,
DSO__ORIG_JAVA_JIT, SYMTAB__JAVA_JIT,
DSO__ORIG_BUILD_ID_CACHE, SYMTAB__BUILD_ID_CACHE,
DSO__ORIG_FEDORA, SYMTAB__FEDORA_DEBUGINFO,
DSO__ORIG_UBUNTU, SYMTAB__UBUNTU_DEBUGINFO,
DSO__ORIG_BUILDID, SYMTAB__BUILDID_DEBUGINFO,
DSO__ORIG_DSO, SYMTAB__SYSTEM_PATH_DSO,
DSO__ORIG_GUEST_KMODULE, SYMTAB__GUEST_KMODULE,
DSO__ORIG_KMODULE, SYMTAB__SYSTEM_PATH_KMODULE,
DSO__ORIG_NOT_FOUND, SYMTAB__NOT_FOUND,
}; };
char dso__symtab_origin(const struct dso *self); char dso__symtab_origin(const struct dso *self);
......
...@@ -171,7 +171,7 @@ float perf_top__decay_samples(struct perf_top *top, struct rb_root *root) ...@@ -171,7 +171,7 @@ float perf_top__decay_samples(struct perf_top *top, struct rb_root *root)
{ {
struct sym_entry *syme, *n; struct sym_entry *syme, *n;
float sum_ksamples = 0.0; float sum_ksamples = 0.0;
int snap = !top->display_weighted ? top->sym_counter : 0, j; int snap = !top->display_weighted ? top->sym_evsel->idx : 0, j;
/* Sort the active symbols */ /* Sort the active symbols */
pthread_mutex_lock(&top->active_symbols_lock); pthread_mutex_lock(&top->active_symbols_lock);
...@@ -184,9 +184,9 @@ float perf_top__decay_samples(struct perf_top *top, struct rb_root *root) ...@@ -184,9 +184,9 @@ float perf_top__decay_samples(struct perf_top *top, struct rb_root *root)
if (syme->snap_count != 0) { if (syme->snap_count != 0) {
if ((top->hide_user_symbols && if ((top->hide_user_symbols &&
syme->origin == PERF_RECORD_MISC_USER) || syme->map->dso->kernel == DSO_TYPE_USER) ||
(top->hide_kernel_symbols && (top->hide_kernel_symbols &&
syme->origin == PERF_RECORD_MISC_KERNEL)) { syme->map->dso->kernel == DSO_TYPE_KERNEL)) {
perf_top__remove_active_sym(top, syme); perf_top__remove_active_sym(top, syme);
continue; continue;
} }
......
...@@ -16,8 +16,6 @@ struct sym_entry { ...@@ -16,8 +16,6 @@ struct sym_entry {
struct list_head node; struct list_head node;
unsigned long snap_count; unsigned long snap_count;
double weight; double weight;
int skip;
u8 origin;
struct map *map; struct map *map;
unsigned long count[0]; unsigned long count[0];
}; };
...@@ -41,7 +39,7 @@ struct perf_top { ...@@ -41,7 +39,7 @@ struct perf_top {
u64 exact_samples; u64 exact_samples;
u64 guest_us_samples, guest_kernel_samples; u64 guest_us_samples, guest_kernel_samples;
int print_entries, count_filter, delay_secs; int print_entries, count_filter, delay_secs;
int display_weighted, freq, rb_entries, sym_counter; int display_weighted, freq, rb_entries;
pid_t target_pid, target_tid; pid_t target_pid, target_tid;
bool hide_kernel_symbols, hide_user_symbols, zero; bool hide_kernel_symbols, hide_user_symbols, zero;
const char *cpu_list; const char *cpu_list;
......
...@@ -2643,68 +2643,13 @@ static void print_lat_fmt(void *data, int size __unused) ...@@ -2643,68 +2643,13 @@ static void print_lat_fmt(void *data, int size __unused)
printf("."); printf(".");
if (lock_depth < 0) if (lock_depth < 0)
printf("."); printf(". ");
else else
printf("%d", lock_depth); printf("%d ", lock_depth);
} }
/* taken from Linux, written by Frederic Weisbecker */
static void print_graph_cpu(int cpu)
{
int i;
int log10_this = log10_cpu(cpu);
int log10_all = log10_cpu(cpus);
/*
* Start with a space character - to make it stand out
* to the right a bit when trace output is pasted into
* email:
*/
printf(" ");
/*
* Tricky - we space the CPU field according to the max
* number of online CPUs. On a 2-cpu system it would take
* a maximum of 1 digit - on a 128 cpu system it would
* take up to 3 digits:
*/
for (i = 0; i < log10_all - log10_this; i++)
printf(" ");
printf("%d) ", cpu);
}
#define TRACE_GRAPH_PROCINFO_LENGTH 14
#define TRACE_GRAPH_INDENT 2 #define TRACE_GRAPH_INDENT 2
static void print_graph_proc(int pid, const char *comm)
{
/* sign + log10(MAX_INT) + '\0' */
char pid_str[11];
int spaces = 0;
int len;
int i;
sprintf(pid_str, "%d", pid);
/* 1 stands for the "-" character */
len = strlen(comm) + strlen(pid_str) + 1;
if (len < TRACE_GRAPH_PROCINFO_LENGTH)
spaces = TRACE_GRAPH_PROCINFO_LENGTH - len;
/* First spaces to align center */
for (i = 0; i < spaces / 2; i++)
printf(" ");
printf("%s-%s", comm, pid_str);
/* Last spaces to align center */
for (i = 0; i < spaces - (spaces / 2); i++)
printf(" ");
}
static struct record * static struct record *
get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func, get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func,
struct record *next) struct record *next)
...@@ -2876,21 +2821,13 @@ static void print_graph_nested(struct event *event, void *data) ...@@ -2876,21 +2821,13 @@ static void print_graph_nested(struct event *event, void *data)
static void static void
pretty_print_func_ent(void *data, int size, struct event *event, pretty_print_func_ent(void *data, int size, struct event *event,
int cpu, int pid, const char *comm, int cpu, int pid)
unsigned long secs, unsigned long usecs)
{ {
struct format_field *field; struct format_field *field;
struct record *rec; struct record *rec;
void *copy_data; void *copy_data;
unsigned long val; unsigned long val;
printf("%5lu.%06lu | ", secs, usecs);
print_graph_cpu(cpu);
print_graph_proc(pid, comm);
printf(" | ");
if (latency_format) { if (latency_format) {
print_lat_fmt(data, size); print_lat_fmt(data, size);
printf(" | "); printf(" | ");
...@@ -2923,22 +2860,13 @@ pretty_print_func_ent(void *data, int size, struct event *event, ...@@ -2923,22 +2860,13 @@ pretty_print_func_ent(void *data, int size, struct event *event,
} }
static void static void
pretty_print_func_ret(void *data, int size __unused, struct event *event, pretty_print_func_ret(void *data, int size __unused, struct event *event)
int cpu, int pid, const char *comm,
unsigned long secs, unsigned long usecs)
{ {
unsigned long long rettime, calltime; unsigned long long rettime, calltime;
unsigned long long duration, depth; unsigned long long duration, depth;
struct format_field *field; struct format_field *field;
int i; int i;
printf("%5lu.%06lu | ", secs, usecs);
print_graph_cpu(cpu);
print_graph_proc(pid, comm);
printf(" | ");
if (latency_format) { if (latency_format) {
print_lat_fmt(data, size); print_lat_fmt(data, size);
printf(" | "); printf(" | ");
...@@ -2976,31 +2904,21 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event, ...@@ -2976,31 +2904,21 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event,
static void static void
pretty_print_func_graph(void *data, int size, struct event *event, pretty_print_func_graph(void *data, int size, struct event *event,
int cpu, int pid, const char *comm, int cpu, int pid)
unsigned long secs, unsigned long usecs)
{ {
if (event->flags & EVENT_FL_ISFUNCENT) if (event->flags & EVENT_FL_ISFUNCENT)
pretty_print_func_ent(data, size, event, pretty_print_func_ent(data, size, event, cpu, pid);
cpu, pid, comm, secs, usecs);
else if (event->flags & EVENT_FL_ISFUNCRET) else if (event->flags & EVENT_FL_ISFUNCRET)
pretty_print_func_ret(data, size, event, pretty_print_func_ret(data, size, event);
cpu, pid, comm, secs, usecs);
printf("\n"); printf("\n");
} }
void print_event(int cpu, void *data, int size, unsigned long long nsecs, void print_trace_event(int cpu, void *data, int size)
char *comm)
{ {
struct event *event; struct event *event;
unsigned long secs;
unsigned long usecs;
int type; int type;
int pid; int pid;
secs = nsecs / NSECS_PER_SEC;
nsecs -= secs * NSECS_PER_SEC;
usecs = nsecs / NSECS_PER_USEC;
type = trace_parse_common_type(data); type = trace_parse_common_type(data);
event = trace_find_event(type); event = trace_find_event(type);
...@@ -3012,17 +2930,10 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, ...@@ -3012,17 +2930,10 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
pid = trace_parse_common_pid(data); pid = trace_parse_common_pid(data);
if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET)) if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET))
return pretty_print_func_graph(data, size, event, cpu, return pretty_print_func_graph(data, size, event, cpu, pid);
pid, comm, secs, usecs);
if (latency_format) { if (latency_format)
printf("%8.8s-%-5d %3d",
comm, pid, cpu);
print_lat_fmt(data, size); print_lat_fmt(data, size);
} else
printf("%16s-%-5d [%03d]", comm, pid, cpu);
printf(" %5lu.%06lu: %s: ", secs, usecs, event->name);
if (event->flags & EVENT_FL_FAILED) { if (event->flags & EVENT_FL_FAILED) {
printf("EVENT '%s' FAILED TO PARSE\n", printf("EVENT '%s' FAILED TO PARSE\n",
...@@ -3031,7 +2942,6 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, ...@@ -3031,7 +2942,6 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
} }
pretty_print(data, size, event); pretty_print(data, size, event);
printf("\n");
} }
static void print_fields(struct print_flag_sym *field) static void print_fields(struct print_flag_sym *field)
......
...@@ -36,11 +36,10 @@ static int stop_script_unsupported(void) ...@@ -36,11 +36,10 @@ static int stop_script_unsupported(void)
return 0; return 0;
} }
static void process_event_unsupported(int cpu __unused, static void process_event_unsupported(union perf_event *event __unused,
void *data __unused, struct perf_sample *sample __unused,
int size __unused, struct perf_session *session __unused,
unsigned long long nsecs __unused, struct thread *thread __unused)
char *comm __unused)
{ {
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "parse-events.h" #include "parse-events.h"
#include "session.h"
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
...@@ -176,8 +177,7 @@ void print_printk(void); ...@@ -176,8 +177,7 @@ void print_printk(void);
int parse_ftrace_file(char *buf, unsigned long size); int parse_ftrace_file(char *buf, unsigned long size);
int parse_event_file(char *buf, unsigned long size, char *sys); int parse_event_file(char *buf, unsigned long size, char *sys);
void print_event(int cpu, void *data, int size, unsigned long long nsecs, void print_trace_event(int cpu, void *data, int size);
char *comm);
extern int file_bigendian; extern int file_bigendian;
extern int host_bigendian; extern int host_bigendian;
...@@ -278,8 +278,10 @@ struct scripting_ops { ...@@ -278,8 +278,10 @@ struct scripting_ops {
const char *name; const char *name;
int (*start_script) (const char *script, int argc, const char **argv); int (*start_script) (const char *script, int argc, const char **argv);
int (*stop_script) (void); int (*stop_script) (void);
void (*process_event) (int cpu, void *data, int size, void (*process_event) (union perf_event *event,
unsigned long long nsecs, char *comm); struct perf_sample *sample,
struct perf_session *session,
struct thread *thread);
int (*generate_script) (const char *outfile); int (*generate_script) (const char *outfile);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment