Skip to content

Commit

Permalink
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/acme/linux into perf/core

perf/core fixes and improvements: perf script improvements and minor fixes.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Ingo Molnar committed Jan 31, 2012
2 parents bb1693f + cfeb1d9 commit 623ec99
Show file tree
Hide file tree
Showing 20 changed files with 149 additions and 56 deletions.
20 changes: 17 additions & 3 deletions tools/perf/Documentation/perf-lock.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ perf-lock - Analyze lock events
SYNOPSIS
--------
[verse]
'perf lock' {record|report|trace}
'perf lock' {record|report|script|info}

DESCRIPTION
-----------
Expand All @@ -20,10 +20,13 @@ and statistics with this 'perf lock' command.
produces the file "perf.data" which contains tracing
results of lock events.

'perf lock trace' shows raw lock events.

'perf lock report' reports statistical data.

'perf lock script' shows raw lock events.

'perf lock info' shows metadata like threads or addresses
of lock instances.

COMMON OPTIONS
--------------

Expand All @@ -47,6 +50,17 @@ REPORT OPTIONS
Sorting key. Possible values: acquired (default), contended,
wait_total, wait_max, wait_min.

INFO OPTIONS
------------

-t::
--threads::
dump thread list in perf.data

-m::
--map::
dump map of lock instances (address:name table)

SEE ALSO
--------
linkperf:perf[1]
5 changes: 4 additions & 1 deletion tools/perf/Documentation/perf-script.txt
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ OPTIONS
-f::
--fields::
Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr.
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff.
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,ip,sym and -f trace:time,cpu,trace
Expand Down Expand Up @@ -200,6 +200,9 @@ OPTIONS
It currently includes: cpu and numa topology of the host system.
It can only be used with the perf script report mode.

--show-kernel-path::
Try to resolve the path of [kernel.kallsyms]

SEE ALSO
--------
linkperf:perf-record[1], linkperf:perf-script-perl[1],
Expand Down
1 change: 0 additions & 1 deletion tools/perf/bench/mem-memcpy.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*
* Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
*/
#include <ctype.h>

#include "../perf.h"
#include "../util/util.h"
Expand Down
1 change: 0 additions & 1 deletion tools/perf/bench/mem-memset.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*
* Trivial clone of mem-memcpy.c.
*/
#include <ctype.h>

#include "../perf.h"
#include "../util/util.h"
Expand Down
4 changes: 2 additions & 2 deletions tools/perf/builtin-lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,12 +922,12 @@ static const struct option info_options[] = {
OPT_BOOLEAN('t', "threads", &info_threads,
"dump thread list in perf.data"),
OPT_BOOLEAN('m', "map", &info_map,
"map of lock instances (name:address table)"),
"map of lock instances (address:name table)"),
OPT_END()
};

static const char * const lock_usage[] = {
"perf lock [<options>] {record|trace|report}",
"perf lock [<options>] {record|report|script|info}",
NULL
};

Expand Down
80 changes: 66 additions & 14 deletions tools/perf/builtin-script.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ enum perf_output_field {
PERF_OUTPUT_SYM = 1U << 8,
PERF_OUTPUT_DSO = 1U << 9,
PERF_OUTPUT_ADDR = 1U << 10,
PERF_OUTPUT_SYMOFFSET = 1U << 11,
};

struct output_option {
Expand All @@ -57,6 +58,7 @@ struct output_option {
{.str = "sym", .field = PERF_OUTPUT_SYM},
{.str = "dso", .field = PERF_OUTPUT_DSO},
{.str = "addr", .field = PERF_OUTPUT_ADDR},
{.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
};

/* default set to maintain compatibility with current format */
Expand Down Expand Up @@ -193,6 +195,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
"to symbols.\n");
return -EINVAL;
}
if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
pr_err("Display of offsets requested but symbol is not"
"selected.\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 "
Expand Down Expand Up @@ -300,10 +307,17 @@ static void print_sample_start(struct perf_sample *sample,
} else
evname = __event_name(attr->type, attr->config);

printf("%s: ", evname ? evname : "(unknown)");
printf("%s: ", evname ? evname : "[unknown]");
}
}

static bool is_bts_event(struct perf_event_attr *attr)
{
return ((attr->type == PERF_TYPE_HARDWARE) &&
(attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS) &&
(attr->sample_period == 1));
}

static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
{
if ((attr->type == PERF_TYPE_SOFTWARE) &&
Expand All @@ -312,6 +326,9 @@ static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
(attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
return true;

if (is_bts_event(attr))
return true;

return false;
}

Expand All @@ -323,7 +340,6 @@ static void print_sample_addr(union perf_event *event,
{
struct addr_location al;
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
const char *symname, *dsoname;

printf("%16" PRIx64, sample->addr);

Expand All @@ -343,22 +359,46 @@ static void print_sample_addr(union perf_event *event,
al.sym = map__find_symbol(al.map, al.addr, NULL);

if (PRINT_FIELD(SYM)) {
if (al.sym && al.sym->name)
symname = al.sym->name;
printf(" ");
if (PRINT_FIELD(SYMOFFSET))
symbol__fprintf_symname_offs(al.sym, &al, stdout);
else
symname = "";

printf(" %16s", symname);
symbol__fprintf_symname(al.sym, stdout);
}

if (PRINT_FIELD(DSO)) {
if (al.map && al.map->dso && al.map->dso->name)
dsoname = al.map->dso->name;
else
dsoname = "";
printf(" (");
map__fprintf_dsoname(al.map, stdout);
printf(")");
}
}

printf(" (%s)", dsoname);
static void print_sample_bts(union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct machine *machine,
struct thread *thread)
{
struct perf_event_attr *attr = &evsel->attr;

/* print branch_from information */
if (PRINT_FIELD(IP)) {
if (!symbol_conf.use_callchain)
printf(" ");
else
printf("\n");
perf_event__print_ip(event, sample, machine, evsel,
PRINT_FIELD(SYM), PRINT_FIELD(DSO),
PRINT_FIELD(SYMOFFSET));
}

printf(" => ");

/* print branch_to information */
if (PRINT_FIELD(ADDR))
print_sample_addr(event, sample, machine, thread, attr);

printf("\n");
}

static void process_event(union perf_event *event __unused,
Expand All @@ -374,6 +414,11 @@ static void process_event(union perf_event *event __unused,

print_sample_start(sample, thread, attr);

if (is_bts_event(attr)) {
print_sample_bts(event, sample, evsel, machine, thread);
return;
}

if (PRINT_FIELD(TRACE))
print_trace_event(sample->cpu, sample->raw_data,
sample->raw_size);
Expand All @@ -387,7 +432,8 @@ static void process_event(union perf_event *event __unused,
else
printf("\n");
perf_event__print_ip(event, sample, machine, evsel,
PRINT_FIELD(SYM), PRINT_FIELD(DSO));
PRINT_FIELD(SYM), PRINT_FIELD(DSO),
PRINT_FIELD(SYMOFFSET));
}

printf("\n");
Expand Down Expand Up @@ -1097,7 +1143,10 @@ 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,ip,sym,dso,addr",
"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,symoff",
parse_output_fields),
OPT_BOOLEAN('a', "all-cpus", &system_wide,
"system-wide collection from all CPUs"),
Expand All @@ -1106,6 +1155,9 @@ static const struct option options[] = {
"only display events for these comms"),
OPT_BOOLEAN('I', "show-info", &show_full_info,
"display extended information from perf.data file"),
OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path,
"Show the path of [kernel.kallsyms]"),

OPT_END()
};

Expand Down
2 changes: 1 addition & 1 deletion tools/perf/python/twatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def main():
cpus = perf.cpu_map()
threads = perf.thread_map()
evsel = perf.evsel(task = 1, comm = 1, mmap = 0,
wakeup_events = 1, sample_period = 1,
wakeup_events = 1, watermark = 1,
sample_id_all = 1,
sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU | perf.SAMPLE_TID)
evsel.open(cpus = cpus, threads = threads);
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
}

if (type & PERF_SAMPLE_READ) {
fprintf(stderr, "PERF_SAMPLE_READ is unsuported for now\n");
fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n");
return -1;
}

Expand Down
15 changes: 15 additions & 0 deletions tools/perf/util/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ size_t map__fprintf(struct map *self, FILE *fp)
self->start, self->end, self->pgoff, self->dso->name);
}

size_t map__fprintf_dsoname(struct map *map, FILE *fp)
{
const char *dsoname;

if (map && map->dso && (map->dso->name || map->dso->long_name)) {
if (symbol_conf.show_kernel_path && map->dso->long_name)
dsoname = map->dso->long_name;
else if (map->dso->name)
dsoname = map->dso->name;
} else
dsoname = "[unknown]";

return fprintf(fp, "%s", dsoname);
}

/*
* objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
* map->dso->adjust_symbols==1 for ET_EXEC-like cases.
Expand Down
1 change: 1 addition & 0 deletions tools/perf/util/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ void map__delete(struct map *self);
struct map *map__clone(struct map *self);
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *self, FILE *fp);
size_t map__fprintf_dsoname(struct map *map, FILE *fp);

int map__load(struct map *self, symbol_filter_t filter);
struct symbol *map__find_symbol(struct map *self,
Expand Down
1 change: 0 additions & 1 deletion tools/perf/util/probe-finder.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include <dwarf-regs.h>

#include <linux/bitops.h>
Expand Down
1 change: 0 additions & 1 deletion tools/perf/util/scripting-engines/trace-event-python.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

#include "../../perf.h"
Expand Down
39 changes: 14 additions & 25 deletions tools/perf/util/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -1293,10 +1293,9 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,

void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
struct machine *machine, struct perf_evsel *evsel,
int print_sym, int print_dso)
int print_sym, int print_dso, int print_symoffset)
{
struct addr_location al;
const char *symname, *dsoname;
struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
struct callchain_cursor_node *node;

Expand Down Expand Up @@ -1324,20 +1323,13 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,

printf("\t%16" PRIx64, node->ip);
if (print_sym) {
if (node->sym && node->sym->name)
symname = node->sym->name;
else
symname = "";

printf(" %s", symname);
printf(" ");
symbol__fprintf_symname(node->sym, stdout);
}
if (print_dso) {
if (node->map && node->map->dso && node->map->dso->name)
dsoname = node->map->dso->name;
else
dsoname = "";

printf(" (%s)", dsoname);
printf(" (");
map__fprintf_dsoname(al.map, stdout);
printf(")");
}
printf("\n");

Expand All @@ -1347,21 +1339,18 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
} else {
printf("%16" PRIx64, sample->ip);
if (print_sym) {
if (al.sym && al.sym->name)
symname = al.sym->name;
printf(" ");
if (print_symoffset)
symbol__fprintf_symname_offs(al.sym, &al,
stdout);
else
symname = "";

printf(" %s", symname);
symbol__fprintf_symname(al.sym, stdout);
}

if (print_dso) {
if (al.map && al.map->dso && al.map->dso->name)
dsoname = al.map->dso->name;
else
dsoname = "";

printf(" (%s)", dsoname);
printf(" (");
map__fprintf_dsoname(al.map, stdout);
printf(")");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tools/perf/util/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,

void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
struct machine *machine, struct perf_evsel *evsel,
int print_sym, int print_dso);
int print_sym, int print_dso, int print_symoffset);

int perf_session__cpu_bitmap(struct perf_session *session,
const char *cpu_list, unsigned long *cpu_bitmap);
Expand Down
Loading

0 comments on commit 623ec99

Please sign in to comment.