forked from Minki/linux
Merge branch 'perf/core' of ssh://k/pub/scm/linux/kernel/git/acme/linux into perf/core
This commit is contained in:
commit
aef29bf20b
@ -115,10 +115,10 @@ OPTIONS
|
||||
-f::
|
||||
--fields::
|
||||
Comma separated list of fields to print. Options are:
|
||||
comm, tid, pid, time, cpu, event, trace, sym. Field
|
||||
list can be prepended with the type, trace, sw or hw,
|
||||
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr.
|
||||
Field list can 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
|
||||
e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
|
||||
|
||||
perf script -f <fields>
|
||||
|
||||
@ -132,17 +132,17 @@ OPTIONS
|
||||
The arguments are processed in the order received. A later usage can
|
||||
reset a prior request. e.g.:
|
||||
|
||||
-f trace: -f comm,tid,time,sym
|
||||
-f trace: -f comm,tid,time,ip,sym
|
||||
|
||||
The first -f suppresses trace events (field list is ""), but then the
|
||||
second invocation sets the fields to comm,tid,time,sym. In this case a
|
||||
second invocation sets the fields to comm,tid,time,ip,sym. In this case a
|
||||
warning is given to the user:
|
||||
|
||||
"Overriding previous field request for all events."
|
||||
|
||||
Alternativey, consider the order:
|
||||
|
||||
-f comm,tid,time,sym -f trace:
|
||||
-f comm,tid,time,ip,sym -f trace:
|
||||
|
||||
The first -f sets the fields for all events and the second -f
|
||||
suppresses trace events. The user is given a warning message about
|
||||
|
@ -30,7 +30,10 @@ enum perf_output_field {
|
||||
PERF_OUTPUT_CPU = 1U << 4,
|
||||
PERF_OUTPUT_EVNAME = 1U << 5,
|
||||
PERF_OUTPUT_TRACE = 1U << 6,
|
||||
PERF_OUTPUT_SYM = 1U << 7,
|
||||
PERF_OUTPUT_IP = 1U << 7,
|
||||
PERF_OUTPUT_SYM = 1U << 8,
|
||||
PERF_OUTPUT_DSO = 1U << 9,
|
||||
PERF_OUTPUT_ADDR = 1U << 10,
|
||||
};
|
||||
|
||||
struct output_option {
|
||||
@ -44,7 +47,10 @@ struct output_option {
|
||||
{.str = "cpu", .field = PERF_OUTPUT_CPU},
|
||||
{.str = "event", .field = PERF_OUTPUT_EVNAME},
|
||||
{.str = "trace", .field = PERF_OUTPUT_TRACE},
|
||||
{.str = "ip", .field = PERF_OUTPUT_IP},
|
||||
{.str = "sym", .field = PERF_OUTPUT_SYM},
|
||||
{.str = "dso", .field = PERF_OUTPUT_DSO},
|
||||
{.str = "addr", .field = PERF_OUTPUT_ADDR},
|
||||
};
|
||||
|
||||
/* default set to maintain compatibility with current format */
|
||||
@ -60,7 +66,8 @@ static struct {
|
||||
|
||||
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
|
||||
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
|
||||
PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
|
||||
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
|
||||
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
|
||||
|
||||
.invalid_fields = PERF_OUTPUT_TRACE,
|
||||
},
|
||||
@ -70,7 +77,8 @@ static struct {
|
||||
|
||||
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
|
||||
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
|
||||
PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
|
||||
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
|
||||
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
|
||||
|
||||
.invalid_fields = PERF_OUTPUT_TRACE,
|
||||
},
|
||||
@ -88,7 +96,8 @@ static struct {
|
||||
|
||||
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
|
||||
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
|
||||
PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
|
||||
PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP |
|
||||
PERF_OUTPUT_SYM | PERF_OUTPUT_DSO,
|
||||
|
||||
.invalid_fields = PERF_OUTPUT_TRACE,
|
||||
},
|
||||
@ -157,9 +166,9 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
|
||||
!perf_session__has_traces(session, "record -R"))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(SYM)) {
|
||||
if (PRINT_FIELD(IP)) {
|
||||
if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP",
|
||||
PERF_OUTPUT_SYM))
|
||||
PERF_OUTPUT_IP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!no_callchain &&
|
||||
@ -167,6 +176,24 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
|
||||
symbol_conf.use_callchain = false;
|
||||
}
|
||||
|
||||
if (PRINT_FIELD(ADDR) &&
|
||||
perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR",
|
||||
PERF_OUTPUT_ADDR))
|
||||
return -EINVAL;
|
||||
|
||||
if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
|
||||
pr_err("Display of symbols requested but neither sample IP nor "
|
||||
"sample address\nis selected. Hence, no addresses to convert "
|
||||
"to symbols.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
|
||||
pr_err("Display of DSO requested but neither sample IP nor "
|
||||
"sample address\nis selected. Hence, no addresses to convert "
|
||||
"to DSO.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) &&
|
||||
perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID",
|
||||
PERF_OUTPUT_TID|PERF_OUTPUT_PID))
|
||||
@ -230,7 +257,7 @@ static void print_sample_start(struct perf_sample *sample,
|
||||
if (PRINT_FIELD(COMM)) {
|
||||
if (latency_format)
|
||||
printf("%8.8s ", thread->comm);
|
||||
else if (PRINT_FIELD(SYM) && symbol_conf.use_callchain)
|
||||
else if (PRINT_FIELD(IP) && symbol_conf.use_callchain)
|
||||
printf("%s ", thread->comm);
|
||||
else
|
||||
printf("%16s ", thread->comm);
|
||||
@ -271,6 +298,63 @@ static void print_sample_start(struct perf_sample *sample,
|
||||
}
|
||||
}
|
||||
|
||||
static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
|
||||
{
|
||||
if ((attr->type == PERF_TYPE_SOFTWARE) &&
|
||||
((attr->config == PERF_COUNT_SW_PAGE_FAULTS) ||
|
||||
(attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) ||
|
||||
(attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void print_sample_addr(union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
struct perf_session *session,
|
||||
struct thread *thread,
|
||||
struct perf_event_attr *attr)
|
||||
{
|
||||
struct addr_location al;
|
||||
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
||||
const char *symname, *dsoname;
|
||||
|
||||
printf("%16" PRIx64, sample->addr);
|
||||
|
||||
if (!sample_addr_correlates_sym(attr))
|
||||
return;
|
||||
|
||||
thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
|
||||
event->ip.pid, sample->addr, &al);
|
||||
if (!al.map)
|
||||
thread__find_addr_map(thread, session, cpumode, MAP__VARIABLE,
|
||||
event->ip.pid, sample->addr, &al);
|
||||
|
||||
al.cpu = sample->cpu;
|
||||
al.sym = NULL;
|
||||
|
||||
if (al.map)
|
||||
al.sym = map__find_symbol(al.map, al.addr, NULL);
|
||||
|
||||
if (PRINT_FIELD(SYM)) {
|
||||
if (al.sym && al.sym->name)
|
||||
symname = al.sym->name;
|
||||
else
|
||||
symname = "";
|
||||
|
||||
printf(" %16s", symname);
|
||||
}
|
||||
|
||||
if (PRINT_FIELD(DSO)) {
|
||||
if (al.map && al.map->dso && al.map->dso->name)
|
||||
dsoname = al.map->dso->name;
|
||||
else
|
||||
dsoname = "";
|
||||
|
||||
printf(" (%s)", dsoname);
|
||||
}
|
||||
}
|
||||
|
||||
static void process_event(union perf_event *event __unused,
|
||||
struct perf_sample *sample,
|
||||
struct perf_evsel *evsel,
|
||||
@ -288,12 +372,16 @@ static void process_event(union perf_event *event __unused,
|
||||
print_trace_event(sample->cpu, sample->raw_data,
|
||||
sample->raw_size);
|
||||
|
||||
if (PRINT_FIELD(SYM)) {
|
||||
if (PRINT_FIELD(ADDR))
|
||||
print_sample_addr(event, sample, session, thread, attr);
|
||||
|
||||
if (PRINT_FIELD(IP)) {
|
||||
if (!symbol_conf.use_callchain)
|
||||
printf(" ");
|
||||
else
|
||||
printf("\n");
|
||||
perf_session__print_symbols(event, sample, session);
|
||||
perf_session__print_ip(event, sample, session,
|
||||
PRINT_FIELD(SYM), PRINT_FIELD(DSO));
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
@ -985,7 +1073,7 @@ static const struct option options[] = {
|
||||
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
|
||||
"Look for files with symbols relative to this directory"),
|
||||
OPT_CALLBACK('f', "fields", NULL, "str",
|
||||
"comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym",
|
||||
"comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr",
|
||||
parse_output_fields),
|
||||
|
||||
OPT_END()
|
||||
|
@ -61,6 +61,8 @@
|
||||
#include <locale.h>
|
||||
|
||||
#define DEFAULT_SEPARATOR " "
|
||||
#define CNTR_NOT_SUPPORTED "<not supported>"
|
||||
#define CNTR_NOT_COUNTED "<not counted>"
|
||||
|
||||
static struct perf_event_attr default_attrs[] = {
|
||||
|
||||
@ -448,6 +450,7 @@ static int run_perf_stat(int argc __used, const char **argv)
|
||||
if (verbose)
|
||||
ui__warning("%s event is not supported by the kernel.\n",
|
||||
event_name(counter));
|
||||
counter->supported = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -466,6 +469,7 @@ static int run_perf_stat(int argc __used, const char **argv)
|
||||
die("Not all events could be opened.\n");
|
||||
return -1;
|
||||
}
|
||||
counter->supported = true;
|
||||
}
|
||||
|
||||
if (perf_evlist__set_filters(evsel_list)) {
|
||||
@ -861,7 +865,7 @@ static void print_counter_aggr(struct perf_evsel *counter)
|
||||
if (scaled == -1) {
|
||||
fprintf(stderr, "%*s%s%*s",
|
||||
csv_output ? 0 : 18,
|
||||
"<not counted>",
|
||||
counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
|
||||
csv_sep,
|
||||
csv_output ? 0 : -24,
|
||||
event_name(counter));
|
||||
@ -914,7 +918,8 @@ static void print_counter(struct perf_evsel *counter)
|
||||
csv_output ? 0 : -4,
|
||||
evsel_list->cpus->map[cpu], csv_sep,
|
||||
csv_output ? 0 : 18,
|
||||
"<not counted>", csv_sep,
|
||||
counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
|
||||
csv_sep,
|
||||
csv_output ? 0 : -24,
|
||||
event_name(counter));
|
||||
|
||||
|
@ -474,7 +474,7 @@ static int test__basic_mmap(void)
|
||||
unsigned int nr_events[nsyscalls],
|
||||
expected_nr_events[nsyscalls], i, j;
|
||||
struct perf_evsel *evsels[nsyscalls], *evsel;
|
||||
int sample_size = perf_sample_size(attr.sample_type);
|
||||
int sample_size = __perf_evsel__sample_size(attr.sample_type);
|
||||
|
||||
for (i = 0; i < nsyscalls; ++i) {
|
||||
char name[64];
|
||||
|
@ -35,22 +35,6 @@ const char *perf_event__name(unsigned int id)
|
||||
return perf_event__names[id];
|
||||
}
|
||||
|
||||
int perf_sample_size(u64 sample_type)
|
||||
{
|
||||
u64 mask = sample_type & PERF_SAMPLE_MASK;
|
||||
int size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (mask & (1ULL << i))
|
||||
size++;
|
||||
}
|
||||
|
||||
size *= sizeof(u64);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct perf_sample synth_sample = {
|
||||
.pid = -1,
|
||||
.tid = -1,
|
||||
|
@ -82,8 +82,6 @@ struct perf_sample {
|
||||
struct ip_callchain *callchain;
|
||||
};
|
||||
|
||||
int perf_sample_size(u64 sample_type);
|
||||
|
||||
#define BUILD_ID_SIZE 20
|
||||
|
||||
struct build_id_event {
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "evlist.h"
|
||||
#include "evsel.h"
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
@ -257,19 +256,15 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
|
||||
return evlist->mmap != NULL ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int __perf_evlist__mmap(struct perf_evlist *evlist, struct perf_evsel *evsel,
|
||||
static int __perf_evlist__mmap(struct perf_evlist *evlist,
|
||||
int idx, int prot, int mask, int fd)
|
||||
{
|
||||
evlist->mmap[idx].prev = 0;
|
||||
evlist->mmap[idx].mask = mask;
|
||||
evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
|
||||
MAP_SHARED, fd, 0);
|
||||
if (evlist->mmap[idx].base == MAP_FAILED) {
|
||||
if (evlist->cpus->map[idx] == -1 && evsel->attr.inherit)
|
||||
ui__warning("Inherit is not allowed on per-task "
|
||||
"events using mmap.\n");
|
||||
if (evlist->mmap[idx].base == MAP_FAILED)
|
||||
return -1;
|
||||
}
|
||||
|
||||
perf_evlist__add_pollfd(evlist, fd);
|
||||
return 0;
|
||||
@ -289,7 +284,7 @@ static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int m
|
||||
|
||||
if (output == -1) {
|
||||
output = fd;
|
||||
if (__perf_evlist__mmap(evlist, evsel, cpu,
|
||||
if (__perf_evlist__mmap(evlist, cpu,
|
||||
prot, mask, output) < 0)
|
||||
goto out_unmap;
|
||||
} else {
|
||||
@ -329,7 +324,7 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in
|
||||
|
||||
if (output == -1) {
|
||||
output = fd;
|
||||
if (__perf_evlist__mmap(evlist, evsel, thread,
|
||||
if (__perf_evlist__mmap(evlist, thread,
|
||||
prot, mask, output) < 0)
|
||||
goto out_unmap;
|
||||
} else {
|
||||
@ -460,33 +455,46 @@ int perf_evlist__set_filters(struct perf_evlist *evlist)
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 perf_evlist__sample_type(struct perf_evlist *evlist)
|
||||
bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
u64 type = 0;
|
||||
struct perf_evsel *pos, *first;
|
||||
|
||||
list_for_each_entry(pos, &evlist->entries, node) {
|
||||
if (!type)
|
||||
type = pos->attr.sample_type;
|
||||
else if (type != pos->attr.sample_type)
|
||||
die("non matching sample_type");
|
||||
pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
|
||||
|
||||
list_for_each_entry_continue(pos, &evlist->entries, node) {
|
||||
if (first->attr.sample_type != pos->attr.sample_type)
|
||||
return false;
|
||||
}
|
||||
|
||||
return type;
|
||||
return true;
|
||||
}
|
||||
|
||||
u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *first;
|
||||
|
||||
first = list_entry(evlist->entries.next, struct perf_evsel, node);
|
||||
return first->attr.sample_type;
|
||||
}
|
||||
|
||||
bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist)
|
||||
{
|
||||
struct perf_evsel *pos, *first;
|
||||
|
||||
pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
|
||||
|
||||
list_for_each_entry_continue(pos, &evlist->entries, node) {
|
||||
if (first->attr.sample_id_all != pos->attr.sample_id_all)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
|
||||
{
|
||||
bool value = false, first = true;
|
||||
struct perf_evsel *pos;
|
||||
struct perf_evsel *first;
|
||||
|
||||
list_for_each_entry(pos, &evlist->entries, node) {
|
||||
if (first) {
|
||||
value = pos->attr.sample_id_all;
|
||||
first = false;
|
||||
} else if (value != pos->attr.sample_id_all)
|
||||
die("non matching sample_id_all");
|
||||
}
|
||||
|
||||
return value;
|
||||
first = list_entry(evlist->entries.next, struct perf_evsel, node);
|
||||
return first->attr.sample_id_all;
|
||||
}
|
||||
|
@ -66,7 +66,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
|
||||
void perf_evlist__delete_maps(struct perf_evlist *evlist);
|
||||
int perf_evlist__set_filters(struct perf_evlist *evlist);
|
||||
|
||||
u64 perf_evlist__sample_type(struct perf_evlist *evlist);
|
||||
bool perf_evlist__sample_id_all(const struct perf_evlist *evlist);
|
||||
u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
|
||||
bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
|
||||
|
||||
bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
|
||||
bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
|
||||
#endif /* __PERF_EVLIST_H */
|
||||
|
@ -15,6 +15,22 @@
|
||||
|
||||
#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
|
||||
|
||||
int __perf_evsel__sample_size(u64 sample_type)
|
||||
{
|
||||
u64 mask = sample_type & PERF_SAMPLE_MASK;
|
||||
int size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (mask & (1ULL << i))
|
||||
size++;
|
||||
}
|
||||
|
||||
size *= sizeof(u64);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void perf_evsel__init(struct perf_evsel *evsel,
|
||||
struct perf_event_attr *attr, int idx)
|
||||
{
|
||||
@ -361,6 +377,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
|
||||
array++;
|
||||
}
|
||||
|
||||
data->addr = 0;
|
||||
if (type & PERF_SAMPLE_ADDR) {
|
||||
data->addr = *array;
|
||||
array++;
|
||||
|
@ -61,6 +61,7 @@ struct perf_evsel {
|
||||
off_t id_offset;
|
||||
};
|
||||
struct cgroup_sel *cgrp;
|
||||
bool supported;
|
||||
};
|
||||
|
||||
struct cpu_map;
|
||||
@ -149,4 +150,11 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
|
||||
return __perf_evsel__read(evsel, ncpus, nthreads, true);
|
||||
}
|
||||
|
||||
int __perf_evsel__sample_size(u64 sample_type);
|
||||
|
||||
static inline int perf_evsel__sample_size(struct perf_evsel *evsel)
|
||||
{
|
||||
return __perf_evsel__sample_size(evsel->attr.sample_type);
|
||||
}
|
||||
|
||||
#endif /* __PERF_EVSEL_H */
|
||||
|
@ -247,7 +247,7 @@ struct pyrf_cpu_map {
|
||||
static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
|
||||
PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "cpustr", NULL, NULL, };
|
||||
static char *kwlist[] = { "cpustr", NULL };
|
||||
char *cpustr = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
|
||||
@ -316,7 +316,7 @@ struct pyrf_thread_map {
|
||||
static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
|
||||
PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
static char *kwlist[] = { "pid", "tid", NULL, NULL, };
|
||||
static char *kwlist[] = { "pid", "tid", NULL };
|
||||
int pid = -1, tid = -1;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
|
||||
@ -418,7 +418,9 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
|
||||
"wakeup_events",
|
||||
"bp_type",
|
||||
"bp_addr",
|
||||
"bp_len", NULL, NULL, };
|
||||
"bp_len",
|
||||
NULL
|
||||
};
|
||||
u64 sample_period = 0;
|
||||
u32 disabled = 0,
|
||||
inherit = 0,
|
||||
@ -499,7 +501,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
|
||||
struct thread_map *threads = NULL;
|
||||
PyObject *pcpus = NULL, *pthreads = NULL;
|
||||
int group = 0, inherit = 0;
|
||||
static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL};
|
||||
static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
|
||||
&pcpus, &pthreads, &group, &inherit))
|
||||
@ -582,8 +584,7 @@ static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
|
||||
PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
struct perf_evlist *evlist = &pevlist->evlist;
|
||||
static char *kwlist[] = {"pages", "overwrite",
|
||||
NULL, NULL};
|
||||
static char *kwlist[] = { "pages", "overwrite", NULL };
|
||||
int pages = 128, overwrite = false;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
|
||||
@ -603,7 +604,7 @@ static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
|
||||
PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
struct perf_evlist *evlist = &pevlist->evlist;
|
||||
static char *kwlist[] = {"timeout", NULL, NULL};
|
||||
static char *kwlist[] = { "timeout", NULL };
|
||||
int timeout = -1, n;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
|
||||
@ -674,7 +675,7 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
|
||||
struct perf_evlist *evlist = &pevlist->evlist;
|
||||
union perf_event *event;
|
||||
int sample_id_all = 1, cpu;
|
||||
static char *kwlist[] = {"sample_id_all", NULL, NULL};
|
||||
static char *kwlist[] = { "cpu", "sample_id_all", NULL };
|
||||
int err;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
|
||||
@ -692,16 +693,14 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
|
||||
|
||||
first = list_entry(evlist->entries.next, struct perf_evsel, node);
|
||||
err = perf_event__parse_sample(event, first->attr.sample_type,
|
||||
perf_sample_size(first->attr.sample_type),
|
||||
perf_evsel__sample_size(first),
|
||||
sample_id_all, &pevent->sample);
|
||||
if (err) {
|
||||
pr_err("Can't parse sample, err = %d\n", err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (err)
|
||||
return PyErr_Format(PyExc_OSError,
|
||||
"perf: can't parse sample, err=%d", err);
|
||||
return pyevent;
|
||||
}
|
||||
end:
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
@ -58,6 +58,16 @@ static int perf_session__open(struct perf_session *self, bool force)
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if (!perf_evlist__valid_sample_type(self->evlist)) {
|
||||
pr_err("non matching sample_type");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if (!perf_evlist__valid_sample_id_all(self->evlist)) {
|
||||
pr_err("non matching sample_id_all");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
self->size = input_stat.st_size;
|
||||
return 0;
|
||||
|
||||
@ -97,7 +107,7 @@ out:
|
||||
void perf_session__update_sample_type(struct perf_session *self)
|
||||
{
|
||||
self->sample_type = perf_evlist__sample_type(self->evlist);
|
||||
self->sample_size = perf_sample_size(self->sample_type);
|
||||
self->sample_size = __perf_evsel__sample_size(self->sample_type);
|
||||
self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
|
||||
perf_session__id_header_size(self);
|
||||
}
|
||||
@ -698,9 +708,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
|
||||
if (!dump_trace)
|
||||
return;
|
||||
|
||||
printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 "\n",
|
||||
printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n",
|
||||
event->header.misc, sample->pid, sample->tid, sample->ip,
|
||||
sample->period);
|
||||
sample->period, sample->addr);
|
||||
|
||||
if (session->sample_type & PERF_SAMPLE_CALLCHAIN)
|
||||
callchain__printf(sample);
|
||||
@ -1192,9 +1202,10 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void perf_session__print_symbols(union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
struct perf_session *session)
|
||||
void perf_session__print_ip(union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
struct perf_session *session,
|
||||
int print_sym, int print_dso)
|
||||
{
|
||||
struct addr_location al;
|
||||
const char *symname, *dsoname;
|
||||
@ -1223,32 +1234,46 @@ void perf_session__print_symbols(union perf_event *event,
|
||||
if (!node)
|
||||
break;
|
||||
|
||||
if (node->sym && node->sym->name)
|
||||
symname = node->sym->name;
|
||||
else
|
||||
symname = "";
|
||||
printf("\t%16" PRIx64, node->ip);
|
||||
if (print_sym) {
|
||||
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(" %s", symname);
|
||||
}
|
||||
if (print_dso) {
|
||||
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);
|
||||
printf(" (%s)", dsoname);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
callchain_cursor_advance(cursor);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (al.sym && al.sym->name)
|
||||
symname = al.sym->name;
|
||||
else
|
||||
symname = "";
|
||||
printf("%16" PRIx64, al.addr);
|
||||
if (print_sym) {
|
||||
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(" %s", symname);
|
||||
}
|
||||
|
||||
printf("%16" PRIx64 " %s (%s)", al.addr, symname, dsoname);
|
||||
if (print_dso) {
|
||||
if (al.map && al.map->dso && al.map->dso->name)
|
||||
dsoname = al.map->dso->name;
|
||||
else
|
||||
dsoname = "";
|
||||
|
||||
printf(" (%s)", dsoname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,8 +167,9 @@ static inline int perf_session__parse_sample(struct perf_session *session,
|
||||
struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
|
||||
unsigned int type);
|
||||
|
||||
void perf_session__print_symbols(union perf_event *event,
|
||||
void perf_session__print_ip(union perf_event *event,
|
||||
struct perf_sample *sample,
|
||||
struct perf_session *session);
|
||||
struct perf_session *session,
|
||||
int print_sym, int print_dso);
|
||||
|
||||
#endif /* __PERF_SESSION_H */
|
||||
|
Loading…
Reference in New Issue
Block a user