Skip to content

Commit

Permalink
Merge branch 'perf/core' of ssh://k/pub/scm/linux/kernel/git/acme/lin…
Browse files Browse the repository at this point in the history
…ux into perf/core
  • Loading branch information
Ingo Molnar committed Jun 3, 2011
2 parents 27eb4a1 + 7cec092 commit aef29bf
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 110 deletions.
12 changes: 6 additions & 6 deletions tools/perf/Documentation/perf-script.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand All @@ -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
Expand Down
108 changes: 98 additions & 10 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 */
Expand All @@ -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,
},
Expand All @@ -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,
},
Expand All @@ -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,
},
Expand Down Expand Up @@ -157,16 +166,34 @@ 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 &&
!(attr->sample_type & PERF_SAMPLE_CALLCHAIN))
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))
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand All @@ -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");
Expand Down Expand Up @@ -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()
Expand Down
9 changes: 7 additions & 2 deletions tools/perf/builtin-stat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {

Expand Down Expand Up @@ -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;
}

Expand All @@ -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)) {
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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));

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/builtin-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
16 changes: 0 additions & 16 deletions tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions tools/perf/util/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit aef29bf

Please sign in to comment.