2009-06-03 05:37:05 +08:00
|
|
|
/*
|
|
|
|
* builtin-report.c
|
|
|
|
*
|
|
|
|
* Builtin report command: Analyze the perf.data input file,
|
|
|
|
* look up and read DSOs and symbol information and display
|
|
|
|
* a histogram of results, along various sorting keys.
|
|
|
|
*/
|
2009-05-27 15:10:38 +08:00
|
|
|
#include "builtin.h"
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2009-06-03 05:37:05 +08:00
|
|
|
#include "util/util.h"
|
2013-01-22 17:09:46 +08:00
|
|
|
#include "util/cache.h"
|
2009-06-03 05:37:05 +08:00
|
|
|
|
2011-02-04 19:45:46 +08:00
|
|
|
#include "util/annotate.h"
|
2009-06-04 21:19:47 +08:00
|
|
|
#include "util/color.h"
|
2009-07-02 01:46:08 +08:00
|
|
|
#include <linux/list.h>
|
2009-07-01 23:28:37 +08:00
|
|
|
#include <linux/rbtree.h>
|
2009-05-29 01:55:04 +08:00
|
|
|
#include "util/symbol.h"
|
2009-06-26 22:28:01 +08:00
|
|
|
#include "util/callchain.h"
|
2009-07-01 06:01:20 +08:00
|
|
|
#include "util/strlist.h"
|
2009-08-07 19:55:24 +08:00
|
|
|
#include "util/values.h"
|
2009-05-18 23:45:42 +08:00
|
|
|
|
2009-05-26 15:17:18 +08:00
|
|
|
#include "perf.h"
|
2009-08-17 04:05:48 +08:00
|
|
|
#include "util/debug.h"
|
2011-03-06 08:40:06 +08:00
|
|
|
#include "util/evlist.h"
|
|
|
|
#include "util/evsel.h"
|
2009-06-25 23:05:54 +08:00
|
|
|
#include "util/header.h"
|
2009-12-12 07:24:02 +08:00
|
|
|
#include "util/session.h"
|
2011-11-28 18:30:20 +08:00
|
|
|
#include "util/tool.h"
|
2009-05-26 15:17:18 +08:00
|
|
|
|
|
|
|
#include "util/parse-options.h"
|
|
|
|
#include "util/parse-events.h"
|
|
|
|
|
2009-08-14 18:21:53 +08:00
|
|
|
#include "util/thread.h"
|
2009-09-25 00:02:49 +08:00
|
|
|
#include "util/sort.h"
|
2009-09-28 21:32:55 +08:00
|
|
|
#include "util/hist.h"
|
2012-10-16 07:33:38 +08:00
|
|
|
#include "arch/common.h"
|
2009-08-14 18:21:53 +08:00
|
|
|
|
2011-07-04 19:57:50 +08:00
|
|
|
#include <linux/bitmap.h>
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_report {
|
2011-11-28 18:30:20 +08:00
|
|
|
struct perf_tool tool;
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_session *session;
|
2012-03-20 02:13:29 +08:00
|
|
|
bool force, use_tui, use_gtk, use_stdio;
|
2011-11-17 22:19:04 +08:00
|
|
|
bool hide_unresolved;
|
|
|
|
bool dont_use_callchains;
|
|
|
|
bool show_full_info;
|
|
|
|
bool show_threads;
|
|
|
|
bool inverted_callchain;
|
2013-01-24 23:10:36 +08:00
|
|
|
bool mem_mode;
|
2011-11-17 22:19:04 +08:00
|
|
|
struct perf_read_values show_threads_values;
|
|
|
|
const char *pretty_printing_style;
|
|
|
|
const char *cpu_list;
|
2012-03-16 16:50:54 +08:00
|
|
|
const char *symbol_filter_str;
|
2013-05-14 10:09:04 +08:00
|
|
|
float min_percent;
|
2011-11-17 22:19:04 +08:00
|
|
|
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
|
2011-11-25 18:19:45 +08:00
|
|
|
};
|
2011-07-04 19:57:50 +08:00
|
|
|
|
2013-01-22 17:09:46 +08:00
|
|
|
static int perf_report_config(const char *var, const char *value, void *cb)
|
|
|
|
{
|
|
|
|
if (!strcmp(var, "report.group")) {
|
|
|
|
symbol_conf.event_group = perf_config_bool(var, value);
|
|
|
|
return 0;
|
|
|
|
}
|
2013-05-14 10:09:06 +08:00
|
|
|
if (!strcmp(var, "report.percent-limit")) {
|
|
|
|
struct perf_report *rep = cb;
|
|
|
|
rep->min_percent = strtof(value, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
2013-01-22 17:09:46 +08:00
|
|
|
|
|
|
|
return perf_default_config(var, value, cb);
|
|
|
|
}
|
|
|
|
|
2013-01-24 23:10:36 +08:00
|
|
|
static int perf_report__add_mem_hist_entry(struct perf_tool *tool,
|
|
|
|
struct addr_location *al,
|
|
|
|
struct perf_sample *sample,
|
|
|
|
struct perf_evsel *evsel,
|
|
|
|
struct machine *machine,
|
|
|
|
union perf_event *event)
|
|
|
|
{
|
|
|
|
struct perf_report *rep = container_of(tool, struct perf_report, tool);
|
|
|
|
struct symbol *parent = NULL;
|
|
|
|
u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
|
|
|
|
int err = 0;
|
|
|
|
struct hist_entry *he;
|
|
|
|
struct mem_info *mi, *mx;
|
|
|
|
uint64_t cost;
|
|
|
|
|
|
|
|
if ((sort__has_parent || symbol_conf.use_callchain) &&
|
|
|
|
sample->callchain) {
|
|
|
|
err = machine__resolve_callchain(machine, evsel, al->thread,
|
2012-12-07 13:48:05 +08:00
|
|
|
sample, &parent, al);
|
2013-01-24 23:10:36 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
mi = machine__resolve_mem(machine, al->thread, sample, cpumode);
|
|
|
|
if (!mi)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
if (rep->hide_unresolved && !al->sym)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
cost = sample->weight;
|
|
|
|
if (!cost)
|
|
|
|
cost = 1;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* must pass period=weight in order to get the correct
|
|
|
|
* sorting from hists__collapse_resort() which is solely
|
|
|
|
* based on periods. We want sorting be done on nr_events * weight
|
|
|
|
* and this is indirectly achieved by passing period=weight here
|
|
|
|
* and the he_stat__add_period() function.
|
|
|
|
*/
|
|
|
|
he = __hists__add_mem_entry(&evsel->hists, al, parent, mi, cost, cost);
|
|
|
|
if (!he)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
/*
|
2013-03-28 22:34:10 +08:00
|
|
|
* In the TUI browser, we are doing integrated annotation,
|
2013-01-24 23:10:36 +08:00
|
|
|
* so we don't allocate the extra space needed because the stdio
|
|
|
|
* code will not use it.
|
|
|
|
*/
|
|
|
|
if (sort__has_sym && he->ms.sym && use_browser > 0) {
|
|
|
|
struct annotation *notes = symbol__annotation(he->ms.sym);
|
|
|
|
|
|
|
|
assert(evsel != NULL);
|
|
|
|
|
|
|
|
if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sort__has_sym && he->mem_info->daddr.sym && use_browser > 0) {
|
|
|
|
struct annotation *notes;
|
|
|
|
|
|
|
|
mx = he->mem_info;
|
|
|
|
|
|
|
|
notes = symbol__annotation(mx->daddr.sym);
|
|
|
|
if (notes->src == NULL && symbol__alloc_hist(mx->daddr.sym) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = symbol__inc_addr_samples(mx->daddr.sym,
|
|
|
|
mx->daddr.map,
|
|
|
|
evsel->idx,
|
|
|
|
mx->daddr.al_addr);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
evsel->hists.stats.total_period += cost;
|
|
|
|
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
|
|
|
|
err = 0;
|
|
|
|
|
|
|
|
if (symbol_conf.use_callchain) {
|
|
|
|
err = callchain_append(he->callchain,
|
|
|
|
&callchain_cursor,
|
|
|
|
sample->period);
|
|
|
|
}
|
|
|
|
out:
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
|
|
|
|
struct addr_location *al,
|
|
|
|
struct perf_sample *sample,
|
|
|
|
struct perf_evsel *evsel,
|
|
|
|
struct machine *machine)
|
|
|
|
{
|
|
|
|
struct perf_report *rep = container_of(tool, struct perf_report, tool);
|
|
|
|
struct symbol *parent = NULL;
|
|
|
|
int err = 0;
|
|
|
|
unsigned i;
|
|
|
|
struct hist_entry *he;
|
2012-03-09 06:47:48 +08:00
|
|
|
struct branch_info *bi, *bx;
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
|
|
|
|
if ((sort__has_parent || symbol_conf.use_callchain)
|
|
|
|
&& sample->callchain) {
|
2012-08-07 21:20:46 +08:00
|
|
|
err = machine__resolve_callchain(machine, evsel, al->thread,
|
2012-12-07 13:48:05 +08:00
|
|
|
sample, &parent, al);
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
bi = machine__resolve_bstack(machine, al->thread,
|
|
|
|
sample->branch_stack);
|
|
|
|
if (!bi)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
for (i = 0; i < sample->branch_stack->nr; i++) {
|
|
|
|
if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
|
|
|
|
continue;
|
2013-04-01 19:35:17 +08:00
|
|
|
|
|
|
|
err = -ENOMEM;
|
|
|
|
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
/*
|
|
|
|
* The report shows the percentage of total branches captured
|
|
|
|
* and not events sampled. Thus we use a pseudo period of 1.
|
|
|
|
*/
|
|
|
|
he = __hists__add_branch_entry(&evsel->hists, al, parent,
|
2013-01-24 23:10:29 +08:00
|
|
|
&bi[i], 1, 1);
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
if (he) {
|
2012-03-09 06:47:48 +08:00
|
|
|
struct annotation *notes;
|
|
|
|
bx = he->branch_info;
|
2012-09-14 16:35:28 +08:00
|
|
|
if (bx->from.sym && use_browser == 1 && sort__has_sym) {
|
2012-03-09 06:47:48 +08:00
|
|
|
notes = symbol__annotation(bx->from.sym);
|
|
|
|
if (!notes->src
|
|
|
|
&& symbol__alloc_hist(bx->from.sym) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = symbol__inc_addr_samples(bx->from.sym,
|
|
|
|
bx->from.map,
|
|
|
|
evsel->idx,
|
|
|
|
bx->from.al_addr);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2012-09-14 16:35:28 +08:00
|
|
|
if (bx->to.sym && use_browser == 1 && sort__has_sym) {
|
2012-03-09 06:47:48 +08:00
|
|
|
notes = symbol__annotation(bx->to.sym);
|
|
|
|
if (!notes->src
|
|
|
|
&& symbol__alloc_hist(bx->to.sym) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = symbol__inc_addr_samples(bx->to.sym,
|
|
|
|
bx->to.map,
|
|
|
|
evsel->idx,
|
|
|
|
bx->to.al_addr);
|
|
|
|
if (err)
|
|
|
|
goto out;
|
|
|
|
}
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
evsel->hists.stats.total_period += 1;
|
|
|
|
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
|
|
|
|
} else
|
2013-04-01 19:35:17 +08:00
|
|
|
goto out;
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
}
|
2013-04-01 19:35:17 +08:00
|
|
|
err = 0;
|
2012-03-09 06:47:48 +08:00
|
|
|
out:
|
2013-04-01 19:35:17 +08:00
|
|
|
free(bi);
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2011-11-28 17:56:39 +08:00
|
|
|
static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
|
|
|
|
struct addr_location *al,
|
|
|
|
struct perf_sample *sample,
|
|
|
|
struct machine *machine)
|
2009-05-18 23:45:42 +08:00
|
|
|
{
|
2010-03-25 03:40:18 +08:00
|
|
|
struct symbol *parent = NULL;
|
2011-01-14 11:51:58 +08:00
|
|
|
int err = 0;
|
2009-05-28 02:20:24 +08:00
|
|
|
struct hist_entry *he;
|
|
|
|
|
2011-01-29 23:02:00 +08:00
|
|
|
if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
|
2012-08-07 21:20:46 +08:00
|
|
|
err = machine__resolve_callchain(machine, evsel, al->thread,
|
2012-12-07 13:48:05 +08:00
|
|
|
sample, &parent, al);
|
2011-01-14 11:51:58 +08:00
|
|
|
if (err)
|
|
|
|
return err;
|
2010-04-02 21:04:18 +08:00
|
|
|
}
|
2010-03-05 23:51:09 +08:00
|
|
|
|
2013-01-24 23:10:29 +08:00
|
|
|
he = __hists__add_entry(&evsel->hists, al, parent, sample->period,
|
|
|
|
sample->weight);
|
2009-10-03 21:42:45 +08:00
|
|
|
if (he == NULL)
|
2011-01-14 11:51:58 +08:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2010-05-12 10:18:06 +08:00
|
|
|
if (symbol_conf.use_callchain) {
|
2011-11-12 09:10:26 +08:00
|
|
|
err = callchain_append(he->callchain,
|
2012-05-31 13:43:26 +08:00
|
|
|
&callchain_cursor,
|
2011-01-29 23:02:00 +08:00
|
|
|
sample->period);
|
2010-05-12 10:18:06 +08:00
|
|
|
if (err)
|
2011-01-14 11:51:58 +08:00
|
|
|
return err;
|
2010-05-12 10:18:06 +08:00
|
|
|
}
|
|
|
|
/*
|
2013-03-28 22:34:10 +08:00
|
|
|
* Only in the TUI browser we are doing integrated annotation,
|
2010-05-12 10:18:06 +08:00
|
|
|
* so we don't allocated the extra space needed because the stdio
|
|
|
|
* code will not use it.
|
|
|
|
*/
|
2012-09-14 16:35:28 +08:00
|
|
|
if (he->ms.sym != NULL && use_browser == 1 && sort__has_sym) {
|
2011-02-04 23:43:24 +08:00
|
|
|
struct annotation *notes = symbol__annotation(he->ms.sym);
|
2011-03-06 08:40:06 +08:00
|
|
|
|
|
|
|
assert(evsel != NULL);
|
|
|
|
|
|
|
|
err = -ENOMEM;
|
2011-11-12 08:17:32 +08:00
|
|
|
if (notes->src == NULL && symbol__alloc_hist(he->ms.sym) < 0)
|
2011-03-06 08:40:06 +08:00
|
|
|
goto out;
|
|
|
|
|
|
|
|
err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
|
2011-02-04 23:43:24 +08:00
|
|
|
}
|
2011-01-14 11:51:58 +08:00
|
|
|
|
2011-03-06 08:40:06 +08:00
|
|
|
evsel->hists.stats.total_period += sample->period;
|
|
|
|
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
|
|
|
|
out:
|
2010-05-09 23:01:05 +08:00
|
|
|
return err;
|
2009-05-18 23:45:42 +08:00
|
|
|
}
|
|
|
|
|
2010-03-05 23:51:09 +08:00
|
|
|
|
2011-11-28 18:30:20 +08:00
|
|
|
static int process_sample_event(struct perf_tool *tool,
|
2011-11-25 18:19:45 +08:00
|
|
|
union perf_event *event,
|
2011-01-30 00:01:45 +08:00
|
|
|
struct perf_sample *sample,
|
2011-03-16 02:44:01 +08:00
|
|
|
struct perf_evsel *evsel,
|
2011-11-28 17:56:39 +08:00
|
|
|
struct machine *machine)
|
2009-06-04 05:14:49 +08:00
|
|
|
{
|
2011-11-28 18:30:20 +08:00
|
|
|
struct perf_report *rep = container_of(tool, struct perf_report, tool);
|
perf tools: Consolidate symbol resolving across all tools
Now we have a very high level routine for simple tools to
process IP sample events:
int event__preprocess_sample(const event_t *self,
struct addr_location *al,
symbol_filter_t filter)
It receives the event itself and will insert new threads in the
global threads list and resolve the map and symbol, filling all
this info into the new addr_location struct, so that tools like
annotate and report can further process the event by creating
hist_entries in their specific way (with or without callgraphs,
etc).
It in turn uses the new next layer function:
void thread__find_addr_location(struct thread *self, u8 cpumode,
enum map_type type, u64 addr,
struct addr_location *al,
symbol_filter_t filter)
This one will, given a thread (userspace or the kernel kthread
one), will find the given type (MAP__FUNCTION now, MAP__VARIABLE
too in the near future) at the given cpumode, taking vdsos into
account (userspace hit, but kernel symbol) and will fill all
these details in the addr_location given.
Tools that need a more compact API for plain function
resolution, like 'kmem', can use this other one:
struct symbol *thread__find_function(struct thread *self, u64 addr,
symbol_filter_t filter)
So, to resolve a kernel symbol, that is all the 'kmem' tool
needs, its just a matter of calling:
sym = thread__find_function(kthread, addr, NULL);
The 'filter' parameter is needed because we do lazy
parsing/loading of ELF symtabs or /proc/kallsyms.
With this we remove more code duplication all around, which is
always good, huh? :-)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: John Kacur <jkacur@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1259346563-12568-12-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-28 02:29:23 +08:00
|
|
|
struct addr_location al;
|
2013-05-14 10:09:02 +08:00
|
|
|
int ret;
|
2009-12-06 19:08:24 +08:00
|
|
|
|
2011-11-28 17:56:39 +08:00
|
|
|
if (perf_event__preprocess_sample(event, machine, &al, sample,
|
2013-08-08 19:32:22 +08:00
|
|
|
machine->symbol_filter) < 0) {
|
2009-12-16 06:04:41 +08:00
|
|
|
fprintf(stderr, "problem processing %d event, skipping it.\n",
|
2009-06-04 05:14:49 +08:00
|
|
|
event->header.type);
|
|
|
|
return -1;
|
|
|
|
}
|
2009-05-28 02:20:24 +08:00
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (al.filtered || (rep->hide_unresolved && al.sym == NULL))
|
2009-10-04 07:30:48 +08:00
|
|
|
return 0;
|
2009-07-01 06:01:22 +08:00
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
|
2011-07-04 19:57:50 +08:00
|
|
|
return 0;
|
|
|
|
|
2013-04-01 19:35:20 +08:00
|
|
|
if (sort__mode == SORT_MODE__BRANCH) {
|
2013-05-14 10:09:02 +08:00
|
|
|
ret = perf_report__add_branch_hist_entry(tool, &al, sample,
|
|
|
|
evsel, machine);
|
|
|
|
if (ret < 0)
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
pr_debug("problem adding lbr entry, skipping event\n");
|
2013-01-24 23:10:36 +08:00
|
|
|
} else if (rep->mem_mode == 1) {
|
2013-05-14 10:09:02 +08:00
|
|
|
ret = perf_report__add_mem_hist_entry(tool, &al, sample,
|
|
|
|
evsel, machine, event);
|
|
|
|
if (ret < 0)
|
2013-01-24 23:10:36 +08:00
|
|
|
pr_debug("problem adding mem entry, skipping event\n");
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
} else {
|
|
|
|
if (al.map != NULL)
|
|
|
|
al.map->dso->hit = 1;
|
perf symbols: Handle /proc/sys/kernel/kptr_restrict
Perf uses /proc/modules to figure out where kernel modules are loaded.
With the advent of kptr_restrict, non root users get zeroes for all module
start addresses.
So check if kptr_restrict is non zero and don't generate the syntethic
PERF_RECORD_MMAP events for them.
Warn the user about it in perf record and in perf report.
In perf report the reference relocation symbol being zero means that
kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't
use it to fixup symbol addresses when using a valid kallsyms (in the buildid
cache) or vmlinux (in the vmlinux path) build-id located automatically or
specified by the user.
Provide an explanation about it in 'perf report' if kernel samples were taken,
checking if a suitable vmlinux or kallsyms was found/specified.
Restricted /proc/kallsyms don't go to the buildid cache anymore.
Example:
[acme@emilia ~]$ perf record -F 100000 sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check
/proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux file is
not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved even
with a suitable vmlinux or kallsyms file.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ]
[acme@emilia ~]$
[acme@emilia ~]$ perf report --stdio
Kernel address maps (/proc/{kallsyms,modules}) were restricted,
check /proc/sys/kernel/kptr_restrict before running 'perf record'.
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .....................
#
20.24% sleep [kernel.kallsyms] [k] page_fault
20.04% sleep [kernel.kallsyms] [k] filemap_fault
19.78% sleep [kernel.kallsyms] [k] __lru_cache_add
19.69% sleep ld-2.12.so [.] memcpy
14.71% sleep [kernel.kallsyms] [k] dput
4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers
0.73% sleep [kernel.kallsyms] [k] perf_event_comm
0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
This is because it found a suitable vmlinux (build-id checked) in
/lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long
file name).
If we remove that file from the vmlinux path:
[root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \
/lib/modules/2.6.39-rc7+/build/vmlinux.OFF
[acme@emilia ~]$ perf report --stdio
[kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562
not found, continuing without symbols
Kernel address maps (/proc/{kallsyms,modules}) were restricted, check
/proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be
resolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. ......
#
80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a
19.69% sleep ld-2.12.so [.] memcpy
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: David Miller <davem@davemloft.net>
Cc: Dave Jones <davej@redhat.com>
Cc: David Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-26 20:53:51 +08:00
|
|
|
|
2013-05-14 10:09:02 +08:00
|
|
|
ret = perf_evsel__add_hist_entry(evsel, &al, sample, machine);
|
|
|
|
if (ret < 0)
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
pr_debug("problem incrementing symbol period, skipping event\n");
|
2009-05-18 23:45:42 +08:00
|
|
|
}
|
2013-05-14 10:09:02 +08:00
|
|
|
return ret;
|
2009-06-04 05:14:49 +08:00
|
|
|
}
|
2009-06-03 15:38:58 +08:00
|
|
|
|
2011-11-28 18:30:20 +08:00
|
|
|
static int process_read_event(struct perf_tool *tool,
|
2011-11-25 18:19:45 +08:00
|
|
|
union perf_event *event,
|
2012-09-11 06:15:03 +08:00
|
|
|
struct perf_sample *sample __maybe_unused,
|
2011-11-28 17:56:39 +08:00
|
|
|
struct perf_evsel *evsel,
|
2012-09-11 06:15:03 +08:00
|
|
|
struct machine *machine __maybe_unused)
|
2009-06-25 04:46:04 +08:00
|
|
|
{
|
2011-11-28 18:30:20 +08:00
|
|
|
struct perf_report *rep = container_of(tool, struct perf_report, tool);
|
2011-11-28 17:56:39 +08:00
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (rep->show_threads) {
|
2012-06-12 23:34:58 +08:00
|
|
|
const char *name = evsel ? perf_evsel__name(evsel) : "unknown";
|
2011-11-17 22:19:04 +08:00
|
|
|
perf_read_values_add_value(&rep->show_threads_values,
|
2009-08-07 19:55:24 +08:00
|
|
|
event->read.pid, event->read.tid,
|
|
|
|
event->read.id,
|
|
|
|
name,
|
|
|
|
event->read.value);
|
|
|
|
}
|
|
|
|
|
2011-01-23 06:37:02 +08:00
|
|
|
dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
|
2012-06-12 23:34:58 +08:00
|
|
|
evsel ? perf_evsel__name(evsel) : "FAIL",
|
2009-11-28 02:29:22 +08:00
|
|
|
event->read.value);
|
2009-06-25 04:46:04 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-06-12 03:48:41 +08:00
|
|
|
/* For pipe mode, sample_type is not currently set */
|
2011-11-25 18:19:45 +08:00
|
|
|
static int perf_report__setup_sample_type(struct perf_report *rep)
|
2009-06-04 05:14:49 +08:00
|
|
|
{
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_session *self = rep->session;
|
2012-08-02 06:15:52 +08:00
|
|
|
u64 sample_type = perf_evlist__sample_type(self->evlist);
|
2011-11-25 18:19:45 +08:00
|
|
|
|
2012-08-02 06:15:52 +08:00
|
|
|
if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
|
2009-07-05 13:39:17 +08:00
|
|
|
if (sort__has_parent) {
|
2012-05-29 12:22:57 +08:00
|
|
|
ui__error("Selected --sort parent, but no "
|
2011-08-03 23:33:24 +08:00
|
|
|
"callchain data. Did you call "
|
|
|
|
"'perf record' without -g?\n");
|
2009-12-28 07:37:02 +08:00
|
|
|
return -EINVAL;
|
2009-07-05 13:39:17 +08:00
|
|
|
}
|
2009-12-16 06:04:42 +08:00
|
|
|
if (symbol_conf.use_callchain) {
|
2012-05-29 12:22:57 +08:00
|
|
|
ui__error("Selected -g but no callchain data. Did "
|
2011-08-03 23:33:24 +08:00
|
|
|
"you call 'perf record' without -g?\n");
|
2009-10-07 18:47:31 +08:00
|
|
|
return -1;
|
2009-07-05 13:39:17 +08:00
|
|
|
}
|
2011-11-17 22:19:04 +08:00
|
|
|
} else if (!rep->dont_use_callchains &&
|
|
|
|
callchain_param.mode != CHAIN_NONE &&
|
2010-01-05 21:54:45 +08:00
|
|
|
!symbol_conf.use_callchain) {
|
2009-12-16 06:04:42 +08:00
|
|
|
symbol_conf.use_callchain = true;
|
2011-01-14 11:52:00 +08:00
|
|
|
if (callchain_register_param(&callchain_param) < 0) {
|
2012-05-29 12:22:57 +08:00
|
|
|
ui__error("Can't register callchain params.\n");
|
2009-12-28 07:37:02 +08:00
|
|
|
return -EINVAL;
|
2009-08-08 08:16:24 +08:00
|
|
|
}
|
2009-06-19 05:22:55 +08:00
|
|
|
}
|
|
|
|
|
2013-04-01 19:35:20 +08:00
|
|
|
if (sort__mode == SORT_MODE__BRANCH) {
|
2012-06-12 03:48:41 +08:00
|
|
|
if (!self->fd_pipe &&
|
2012-08-02 06:15:52 +08:00
|
|
|
!(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
|
2012-05-29 12:22:57 +08:00
|
|
|
ui__error("Selected -b but no branch data. "
|
|
|
|
"Did you call perf record without -b?\n");
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-07 18:47:31 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2009-05-27 02:51:47 +08:00
|
|
|
|
2010-04-02 12:59:17 +08:00
|
|
|
extern volatile int session_done;
|
|
|
|
|
2012-09-11 06:15:03 +08:00
|
|
|
static void sig_handler(int sig __maybe_unused)
|
2010-04-02 12:59:17 +08:00
|
|
|
{
|
|
|
|
session_done = 1;
|
|
|
|
}
|
|
|
|
|
2013-01-24 23:10:36 +08:00
|
|
|
static size_t hists__fprintf_nr_sample_events(struct perf_report *rep,
|
|
|
|
struct hists *self,
|
2010-05-15 01:19:35 +08:00
|
|
|
const char *evname, FILE *fp)
|
|
|
|
{
|
|
|
|
size_t ret;
|
|
|
|
char unit;
|
2012-04-06 10:01:01 +08:00
|
|
|
unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE];
|
|
|
|
u64 nr_events = self->stats.total_period;
|
2013-01-22 17:09:44 +08:00
|
|
|
struct perf_evsel *evsel = hists_to_evsel(self);
|
|
|
|
char buf[512];
|
|
|
|
size_t size = sizeof(buf);
|
|
|
|
|
2013-03-05 13:53:26 +08:00
|
|
|
if (perf_evsel__is_group_event(evsel)) {
|
2013-01-22 17:09:44 +08:00
|
|
|
struct perf_evsel *pos;
|
|
|
|
|
|
|
|
perf_evsel__group_desc(evsel, buf, size);
|
|
|
|
evname = buf;
|
|
|
|
|
|
|
|
for_each_group_member(pos, evsel) {
|
|
|
|
nr_samples += pos->hists.stats.nr_events[PERF_RECORD_SAMPLE];
|
|
|
|
nr_events += pos->hists.stats.total_period;
|
|
|
|
}
|
|
|
|
}
|
2010-05-15 01:19:35 +08:00
|
|
|
|
2012-04-06 10:01:01 +08:00
|
|
|
nr_samples = convert_unit(nr_samples, &unit);
|
|
|
|
ret = fprintf(fp, "# Samples: %lu%c", nr_samples, unit);
|
2010-05-15 01:19:35 +08:00
|
|
|
if (evname != NULL)
|
2012-04-06 10:01:01 +08:00
|
|
|
ret += fprintf(fp, " of event '%s'", evname);
|
|
|
|
|
2013-01-24 23:10:36 +08:00
|
|
|
if (rep->mem_mode) {
|
|
|
|
ret += fprintf(fp, "\n# Total weight : %" PRIu64, nr_events);
|
|
|
|
ret += fprintf(fp, "\n# Sort order : %s", sort_order);
|
|
|
|
} else
|
|
|
|
ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events);
|
2010-05-15 01:19:35 +08:00
|
|
|
return ret + fprintf(fp, "\n#\n");
|
|
|
|
}
|
|
|
|
|
2011-03-07 00:07:30 +08:00
|
|
|
static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_report *rep,
|
2011-03-07 00:07:30 +08:00
|
|
|
const char *help)
|
2010-05-24 09:36:51 +08:00
|
|
|
{
|
2011-03-06 08:40:06 +08:00
|
|
|
struct perf_evsel *pos;
|
2010-05-24 09:36:51 +08:00
|
|
|
|
2011-03-06 08:40:06 +08:00
|
|
|
list_for_each_entry(pos, &evlist->entries, node) {
|
|
|
|
struct hists *hists = &pos->hists;
|
2012-06-12 23:34:58 +08:00
|
|
|
const char *evname = perf_evsel__name(pos);
|
2010-05-24 09:36:51 +08:00
|
|
|
|
2013-01-22 17:09:43 +08:00
|
|
|
if (symbol_conf.event_group &&
|
|
|
|
!perf_evsel__is_group_leader(pos))
|
|
|
|
continue;
|
|
|
|
|
2013-01-24 23:10:36 +08:00
|
|
|
hists__fprintf_nr_sample_events(rep, hists, evname, stdout);
|
2013-05-14 10:09:04 +08:00
|
|
|
hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
|
2010-05-24 09:36:51 +08:00
|
|
|
fprintf(stdout, "\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sort_order == default_sort_order &&
|
|
|
|
parent_pattern == default_parent_pattern) {
|
|
|
|
fprintf(stdout, "#\n# (%s)\n#\n", help);
|
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (rep->show_threads) {
|
|
|
|
bool style = !strcmp(rep->pretty_printing_style, "raw");
|
|
|
|
perf_read_values_display(stdout, &rep->show_threads_values,
|
2010-05-24 09:36:51 +08:00
|
|
|
style);
|
2011-11-17 22:19:04 +08:00
|
|
|
perf_read_values_destroy(&rep->show_threads_values);
|
2010-05-24 09:36:51 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
static int __cmd_report(struct perf_report *rep)
|
2009-10-07 18:47:31 +08:00
|
|
|
{
|
2009-12-28 07:37:02 +08:00
|
|
|
int ret = -EINVAL;
|
2011-03-06 08:40:06 +08:00
|
|
|
u64 nr_samples;
|
2012-03-09 06:47:47 +08:00
|
|
|
struct perf_session *session = rep->session;
|
2011-03-06 08:40:06 +08:00
|
|
|
struct perf_evsel *pos;
|
perf symbols: Handle /proc/sys/kernel/kptr_restrict
Perf uses /proc/modules to figure out where kernel modules are loaded.
With the advent of kptr_restrict, non root users get zeroes for all module
start addresses.
So check if kptr_restrict is non zero and don't generate the syntethic
PERF_RECORD_MMAP events for them.
Warn the user about it in perf record and in perf report.
In perf report the reference relocation symbol being zero means that
kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't
use it to fixup symbol addresses when using a valid kallsyms (in the buildid
cache) or vmlinux (in the vmlinux path) build-id located automatically or
specified by the user.
Provide an explanation about it in 'perf report' if kernel samples were taken,
checking if a suitable vmlinux or kallsyms was found/specified.
Restricted /proc/kallsyms don't go to the buildid cache anymore.
Example:
[acme@emilia ~]$ perf record -F 100000 sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check
/proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux file is
not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved even
with a suitable vmlinux or kallsyms file.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ]
[acme@emilia ~]$
[acme@emilia ~]$ perf report --stdio
Kernel address maps (/proc/{kallsyms,modules}) were restricted,
check /proc/sys/kernel/kptr_restrict before running 'perf record'.
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .....................
#
20.24% sleep [kernel.kallsyms] [k] page_fault
20.04% sleep [kernel.kallsyms] [k] filemap_fault
19.78% sleep [kernel.kallsyms] [k] __lru_cache_add
19.69% sleep ld-2.12.so [.] memcpy
14.71% sleep [kernel.kallsyms] [k] dput
4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers
0.73% sleep [kernel.kallsyms] [k] perf_event_comm
0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
This is because it found a suitable vmlinux (build-id checked) in
/lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long
file name).
If we remove that file from the vmlinux path:
[root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \
/lib/modules/2.6.39-rc7+/build/vmlinux.OFF
[acme@emilia ~]$ perf report --stdio
[kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562
not found, continuing without symbols
Kernel address maps (/proc/{kallsyms,modules}) were restricted, check
/proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be
resolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. ......
#
80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a
19.69% sleep ld-2.12.so [.] memcpy
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: David Miller <davem@davemloft.net>
Cc: Dave Jones <davej@redhat.com>
Cc: David Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-26 20:53:51 +08:00
|
|
|
struct map *kernel_map;
|
|
|
|
struct kmap *kernel_kmap;
|
2010-03-12 07:12:44 +08:00
|
|
|
const char *help = "For a higher level overview, try: perf report --sort comm,dso";
|
2009-05-18 23:45:42 +08:00
|
|
|
|
2010-04-02 12:59:17 +08:00
|
|
|
signal(SIGINT, sig_handler);
|
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (rep->cpu_list) {
|
|
|
|
ret = perf_session__cpu_bitmap(session, rep->cpu_list,
|
|
|
|
rep->cpu_bitmap);
|
2011-07-04 19:57:50 +08:00
|
|
|
if (ret)
|
2013-06-25 19:54:13 +08:00
|
|
|
return ret;
|
2011-07-04 19:57:50 +08:00
|
|
|
}
|
|
|
|
|
perf tools: Make perf.data more self-descriptive (v8)
The goal of this patch is to include more information about the host
environment into the perf.data so it is more self-descriptive. Overtime,
profiles are captured on various machines and it becomes hard to track
what was recorded, on what machine and when.
This patch provides a way to solve this by extending the perf.data file
with basic information about the host machine. To add those extensions,
we leverage the feature bits capabilities of the perf.data format. The
change is backward compatible with existing perf.data files.
We define the following useful new extensions:
- HEADER_HOSTNAME: the hostname
- HEADER_OSRELEASE: the kernel release number
- HEADER_ARCH: the hw architecture
- HEADER_CPUDESC: generic CPU description
- HEADER_NRCPUS: number of online/avail cpus
- HEADER_CMDLINE: perf command line
- HEADER_VERSION: perf version
- HEADER_TOPOLOGY: cpu topology
- HEADER_EVENT_DESC: full event description (attrs)
- HEADER_CPUID: easy-to-parse low level CPU identication
The small granularity for the entries is to make it easier to extend
without breaking backward compatiblity. Many entries are provided as
ASCII strings.
Perf report/script have been modified to print the basic information as
easy-to-parse ASCII strings. Extended information about CPU and NUMA
topology may be requested with the -I option.
Thanks to David Ahern for reviewing and testing the many versions of
this patch.
$ perf report --stdio
# ========
# captured on : Mon Sep 26 15:22:14 2011
# hostname : quad
# os release : 3.1.0-rc4-tip
# perf version : 3.1.0-rc4
# arch : x86_64
# nrcpus online : 4
# nrcpus avail : 4
# cpudesc : Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 8105360 kB
# cmdline : /home/eranian/perfmon/official/tip/build/tools/perf/perf record date
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 29, 30, 31,
# HEADER_CPU_TOPOLOGY info available, use -I to display
# HEADER_NUMA_TOPOLOGY info available, use -I to display
# ========
#
...
$ perf report --stdio -I
# ========
# captured on : Mon Sep 26 15:22:14 2011
# hostname : quad
# os release : 3.1.0-rc4-tip
# perf version : 3.1.0-rc4
# arch : x86_64
# nrcpus online : 4
# nrcpus avail : 4
# cpudesc : Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 8105360 kB
# cmdline : /home/eranian/perfmon/official/tip/build/tools/perf/perf record date
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 29, 30, 31,
# sibling cores : 0-3
# sibling threads : 0
# sibling threads : 1
# sibling threads : 2
# sibling threads : 3
# node0 meminfo : total = 8320608 kB, free = 7571024 kB
# node0 cpu list : 0-3
# ========
#
...
Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/20110930134040.GA5575@quad
Signed-off-by: Stephane Eranian <eranian@google.com>
[ committer notes: Use --show-info in the tools as was in the docs, rename
perf_header_fprintf_info to perf_file_section__fprintf_info, fixup
conflict with f69b64f7 "perf: Support setting the disassembler style" ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-09-30 21:40:40 +08:00
|
|
|
if (use_browser <= 0)
|
2011-11-17 22:19:04 +08:00
|
|
|
perf_session__fprintf_info(session, stdout, rep->show_full_info);
|
perf tools: Make perf.data more self-descriptive (v8)
The goal of this patch is to include more information about the host
environment into the perf.data so it is more self-descriptive. Overtime,
profiles are captured on various machines and it becomes hard to track
what was recorded, on what machine and when.
This patch provides a way to solve this by extending the perf.data file
with basic information about the host machine. To add those extensions,
we leverage the feature bits capabilities of the perf.data format. The
change is backward compatible with existing perf.data files.
We define the following useful new extensions:
- HEADER_HOSTNAME: the hostname
- HEADER_OSRELEASE: the kernel release number
- HEADER_ARCH: the hw architecture
- HEADER_CPUDESC: generic CPU description
- HEADER_NRCPUS: number of online/avail cpus
- HEADER_CMDLINE: perf command line
- HEADER_VERSION: perf version
- HEADER_TOPOLOGY: cpu topology
- HEADER_EVENT_DESC: full event description (attrs)
- HEADER_CPUID: easy-to-parse low level CPU identication
The small granularity for the entries is to make it easier to extend
without breaking backward compatiblity. Many entries are provided as
ASCII strings.
Perf report/script have been modified to print the basic information as
easy-to-parse ASCII strings. Extended information about CPU and NUMA
topology may be requested with the -I option.
Thanks to David Ahern for reviewing and testing the many versions of
this patch.
$ perf report --stdio
# ========
# captured on : Mon Sep 26 15:22:14 2011
# hostname : quad
# os release : 3.1.0-rc4-tip
# perf version : 3.1.0-rc4
# arch : x86_64
# nrcpus online : 4
# nrcpus avail : 4
# cpudesc : Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 8105360 kB
# cmdline : /home/eranian/perfmon/official/tip/build/tools/perf/perf record date
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 29, 30, 31,
# HEADER_CPU_TOPOLOGY info available, use -I to display
# HEADER_NUMA_TOPOLOGY info available, use -I to display
# ========
#
...
$ perf report --stdio -I
# ========
# captured on : Mon Sep 26 15:22:14 2011
# hostname : quad
# os release : 3.1.0-rc4-tip
# perf version : 3.1.0-rc4
# arch : x86_64
# nrcpus online : 4
# nrcpus avail : 4
# cpudesc : Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 8105360 kB
# cmdline : /home/eranian/perfmon/official/tip/build/tools/perf/perf record date
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 29, 30, 31,
# sibling cores : 0-3
# sibling threads : 0
# sibling threads : 1
# sibling threads : 2
# sibling threads : 3
# node0 meminfo : total = 8320608 kB, free = 7571024 kB
# node0 cpu list : 0-3
# ========
#
...
Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/20110930134040.GA5575@quad
Signed-off-by: Stephane Eranian <eranian@google.com>
[ committer notes: Use --show-info in the tools as was in the docs, rename
perf_header_fprintf_info to perf_file_section__fprintf_info, fixup
conflict with f69b64f7 "perf: Support setting the disassembler style" ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-09-30 21:40:40 +08:00
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (rep->show_threads)
|
|
|
|
perf_read_values_init(&rep->show_threads_values);
|
2009-06-19 05:22:55 +08:00
|
|
|
|
2011-11-25 18:19:45 +08:00
|
|
|
ret = perf_report__setup_sample_type(rep);
|
2009-12-28 07:37:02 +08:00
|
|
|
if (ret)
|
2013-06-25 19:54:13 +08:00
|
|
|
return ret;
|
2009-12-28 07:37:02 +08:00
|
|
|
|
2011-11-28 18:30:20 +08:00
|
|
|
ret = perf_session__process_events(session, &rep->tool);
|
2009-10-07 18:47:31 +08:00
|
|
|
if (ret)
|
2013-06-25 19:54:13 +08:00
|
|
|
return ret;
|
2009-05-27 00:48:58 +08:00
|
|
|
|
2012-12-19 06:15:48 +08:00
|
|
|
kernel_map = session->machines.host.vmlinux_maps[MAP__FUNCTION];
|
perf symbols: Handle /proc/sys/kernel/kptr_restrict
Perf uses /proc/modules to figure out where kernel modules are loaded.
With the advent of kptr_restrict, non root users get zeroes for all module
start addresses.
So check if kptr_restrict is non zero and don't generate the syntethic
PERF_RECORD_MMAP events for them.
Warn the user about it in perf record and in perf report.
In perf report the reference relocation symbol being zero means that
kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't
use it to fixup symbol addresses when using a valid kallsyms (in the buildid
cache) or vmlinux (in the vmlinux path) build-id located automatically or
specified by the user.
Provide an explanation about it in 'perf report' if kernel samples were taken,
checking if a suitable vmlinux or kallsyms was found/specified.
Restricted /proc/kallsyms don't go to the buildid cache anymore.
Example:
[acme@emilia ~]$ perf record -F 100000 sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check
/proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux file is
not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved even
with a suitable vmlinux or kallsyms file.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ]
[acme@emilia ~]$
[acme@emilia ~]$ perf report --stdio
Kernel address maps (/proc/{kallsyms,modules}) were restricted,
check /proc/sys/kernel/kptr_restrict before running 'perf record'.
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .....................
#
20.24% sleep [kernel.kallsyms] [k] page_fault
20.04% sleep [kernel.kallsyms] [k] filemap_fault
19.78% sleep [kernel.kallsyms] [k] __lru_cache_add
19.69% sleep ld-2.12.so [.] memcpy
14.71% sleep [kernel.kallsyms] [k] dput
4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers
0.73% sleep [kernel.kallsyms] [k] perf_event_comm
0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
This is because it found a suitable vmlinux (build-id checked) in
/lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long
file name).
If we remove that file from the vmlinux path:
[root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \
/lib/modules/2.6.39-rc7+/build/vmlinux.OFF
[acme@emilia ~]$ perf report --stdio
[kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562
not found, continuing without symbols
Kernel address maps (/proc/{kallsyms,modules}) were restricted, check
/proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be
resolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. ......
#
80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a
19.69% sleep ld-2.12.so [.] memcpy
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: David Miller <davem@davemloft.net>
Cc: Dave Jones <davej@redhat.com>
Cc: David Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-26 20:53:51 +08:00
|
|
|
kernel_kmap = map__kmap(kernel_map);
|
|
|
|
if (kernel_map == NULL ||
|
|
|
|
(kernel_map->dso->hit &&
|
|
|
|
(kernel_kmap->ref_reloc_sym == NULL ||
|
|
|
|
kernel_kmap->ref_reloc_sym->addr == 0))) {
|
2012-04-16 10:54:15 +08:00
|
|
|
const char *desc =
|
|
|
|
"As no suitable kallsyms nor vmlinux was found, kernel samples\n"
|
|
|
|
"can't be resolved.";
|
|
|
|
|
|
|
|
if (kernel_map) {
|
|
|
|
const struct dso *kdso = kernel_map->dso;
|
|
|
|
if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) {
|
|
|
|
desc = "If some relocation was applied (e.g. "
|
|
|
|
"kexec) symbols may be misresolved.";
|
|
|
|
}
|
|
|
|
}
|
perf symbols: Handle /proc/sys/kernel/kptr_restrict
Perf uses /proc/modules to figure out where kernel modules are loaded.
With the advent of kptr_restrict, non root users get zeroes for all module
start addresses.
So check if kptr_restrict is non zero and don't generate the syntethic
PERF_RECORD_MMAP events for them.
Warn the user about it in perf record and in perf report.
In perf report the reference relocation symbol being zero means that
kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't
use it to fixup symbol addresses when using a valid kallsyms (in the buildid
cache) or vmlinux (in the vmlinux path) build-id located automatically or
specified by the user.
Provide an explanation about it in 'perf report' if kernel samples were taken,
checking if a suitable vmlinux or kallsyms was found/specified.
Restricted /proc/kallsyms don't go to the buildid cache anymore.
Example:
[acme@emilia ~]$ perf record -F 100000 sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check
/proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux file is
not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved even
with a suitable vmlinux or kallsyms file.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ]
[acme@emilia ~]$
[acme@emilia ~]$ perf report --stdio
Kernel address maps (/proc/{kallsyms,modules}) were restricted,
check /proc/sys/kernel/kptr_restrict before running 'perf record'.
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .....................
#
20.24% sleep [kernel.kallsyms] [k] page_fault
20.04% sleep [kernel.kallsyms] [k] filemap_fault
19.78% sleep [kernel.kallsyms] [k] __lru_cache_add
19.69% sleep ld-2.12.so [.] memcpy
14.71% sleep [kernel.kallsyms] [k] dput
4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers
0.73% sleep [kernel.kallsyms] [k] perf_event_comm
0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
This is because it found a suitable vmlinux (build-id checked) in
/lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long
file name).
If we remove that file from the vmlinux path:
[root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \
/lib/modules/2.6.39-rc7+/build/vmlinux.OFF
[acme@emilia ~]$ perf report --stdio
[kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562
not found, continuing without symbols
Kernel address maps (/proc/{kallsyms,modules}) were restricted, check
/proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be
resolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. ......
#
80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a
19.69% sleep ld-2.12.so [.] memcpy
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: David Miller <davem@davemloft.net>
Cc: Dave Jones <davej@redhat.com>
Cc: David Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-26 20:53:51 +08:00
|
|
|
|
2011-05-27 22:00:41 +08:00
|
|
|
ui__warning(
|
|
|
|
"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
|
|
|
|
"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
|
|
|
|
"Samples in kernel modules can't be resolved as well.\n\n",
|
2012-04-16 10:54:15 +08:00
|
|
|
desc);
|
perf symbols: Handle /proc/sys/kernel/kptr_restrict
Perf uses /proc/modules to figure out where kernel modules are loaded.
With the advent of kptr_restrict, non root users get zeroes for all module
start addresses.
So check if kptr_restrict is non zero and don't generate the syntethic
PERF_RECORD_MMAP events for them.
Warn the user about it in perf record and in perf report.
In perf report the reference relocation symbol being zero means that
kptr_restrict was set, thus /proc/kallsyms has only zeroed addresses, so don't
use it to fixup symbol addresses when using a valid kallsyms (in the buildid
cache) or vmlinux (in the vmlinux path) build-id located automatically or
specified by the user.
Provide an explanation about it in 'perf report' if kernel samples were taken,
checking if a suitable vmlinux or kallsyms was found/specified.
Restricted /proc/kallsyms don't go to the buildid cache anymore.
Example:
[acme@emilia ~]$ perf record -F 100000 sleep 1
WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted, check
/proc/sys/kernel/kptr_restrict.
Samples in kernel functions may not be resolved if a suitable vmlinux file is
not found in the buildid cache or in the vmlinux path.
Samples in kernel modules won't be resolved at all.
If some relocation was applied (e.g. kexec) symbols may be misresolved even
with a suitable vmlinux or kallsyms file.
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.005 MB perf.data (~231 samples) ]
[acme@emilia ~]$
[acme@emilia ~]$ perf report --stdio
Kernel address maps (/proc/{kallsyms,modules}) were restricted,
check /proc/sys/kernel/kptr_restrict before running 'perf record'.
If some relocation was applied (e.g. kexec) symbols may be misresolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. .....................
#
20.24% sleep [kernel.kallsyms] [k] page_fault
20.04% sleep [kernel.kallsyms] [k] filemap_fault
19.78% sleep [kernel.kallsyms] [k] __lru_cache_add
19.69% sleep ld-2.12.so [.] memcpy
14.71% sleep [kernel.kallsyms] [k] dput
4.70% sleep [kernel.kallsyms] [k] flush_signal_handlers
0.73% sleep [kernel.kallsyms] [k] perf_event_comm
0.11% sleep [kernel.kallsyms] [k] native_write_msr_safe
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
This is because it found a suitable vmlinux (build-id checked) in
/lib/modules/2.6.39-rc7+/build/vmlinux (use -v in perf report to see the long
file name).
If we remove that file from the vmlinux path:
[root@emilia ~]# mv /lib/modules/2.6.39-rc7+/build/vmlinux \
/lib/modules/2.6.39-rc7+/build/vmlinux.OFF
[acme@emilia ~]$ perf report --stdio
[kernel.kallsyms] with build id 57298cdbe0131f6871667ec0eaab4804dcf6f562
not found, continuing without symbols
Kernel address maps (/proc/{kallsyms,modules}) were restricted, check
/proc/sys/kernel/kptr_restrict before running 'perf record'.
As no suitable kallsyms nor vmlinux was found, kernel samples can't be
resolved.
Samples in kernel modules can't be resolved as well.
# Events: 13 cycles
#
# Overhead Command Shared Object Symbol
# ........ ....... ................. ......
#
80.31% sleep [kernel.kallsyms] [k] 0xffffffff8103425a
19.69% sleep ld-2.12.so [.] memcpy
#
# (For a higher level overview, try: perf report --sort comm,dso)
#
[acme@emilia ~]$
Reported-by: Stephane Eranian <eranian@google.com>
Suggested-by: David Miller <davem@davemloft.net>
Cc: Dave Jones <davej@redhat.com>
Cc: David Miller <davem@davemloft.net>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Kees Cook <kees.cook@canonical.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: http://lkml.kernel.org/n/tip-mt512joaxxbhhp1odop04yit@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-05-26 20:53:51 +08:00
|
|
|
}
|
|
|
|
|
2009-10-07 21:49:00 +08:00
|
|
|
if (verbose > 3)
|
2009-12-14 05:50:28 +08:00
|
|
|
perf_session__fprintf(session, stdout);
|
2009-06-05 00:54:00 +08:00
|
|
|
|
2009-10-07 21:49:00 +08:00
|
|
|
if (verbose > 2)
|
2010-04-28 08:22:44 +08:00
|
|
|
perf_session__fprintf_dsos(session, stdout);
|
2009-05-27 15:10:38 +08:00
|
|
|
|
2012-08-07 21:20:46 +08:00
|
|
|
if (dump_trace) {
|
|
|
|
perf_session__fprintf_nr_events(session, stdout);
|
2013-06-25 19:54:13 +08:00
|
|
|
return 0;
|
2012-08-07 21:20:46 +08:00
|
|
|
}
|
|
|
|
|
2011-03-06 08:40:06 +08:00
|
|
|
nr_samples = 0;
|
|
|
|
list_for_each_entry(pos, &session->evlist->entries, node) {
|
|
|
|
struct hists *hists = &pos->hists;
|
2010-03-05 23:51:09 +08:00
|
|
|
|
2012-03-16 16:50:54 +08:00
|
|
|
if (pos->idx == 0)
|
|
|
|
hists->symbol_filter_str = rep->symbol_filter_str;
|
|
|
|
|
perf hist: Introduce hists class and move lots of methods to it
In cbbc79a we introduced support for multiple events by introducing a
new "event_stat_id" struct and then made several perf_session methods
receive a point to it instead of a pointer to perf_session, and kept the
event_stats and hists rb_tree in perf_session.
While working on the new newt based browser, I realised that it would be
better to introduce a new class, "hists" (short for "histograms"),
renaming the "event_stat_id" struct and the perf_session methods that
were really "hists" methods, as they manipulate only struct hists
members, not touching anything in the other perf_session members.
Other optimizations, such as calculating the maximum lenght of a symbol
name present in an hists instance will be possible as we add them,
avoiding a re-traversal just for finding that information.
The rationale for the name "hists" to replace "event_stat_id" is that we
may have multiple sets of hists for the same event_stat id, as, for
instance, the 'perf diff' tool has, so event stat id is not what
characterizes what this struct and the functions that manipulate it do.
Cc: Eric B Munson <ebmunson@us.ibm.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2010-05-11 00:04:11 +08:00
|
|
|
hists__collapse_resort(hists);
|
2011-03-06 08:40:06 +08:00
|
|
|
nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
|
2013-01-22 17:09:32 +08:00
|
|
|
|
|
|
|
/* Non-group events are considered as leader */
|
|
|
|
if (symbol_conf.event_group &&
|
|
|
|
!perf_evsel__is_group_leader(pos)) {
|
|
|
|
struct hists *leader_hists = &pos->leader->hists;
|
|
|
|
|
|
|
|
hists__match(leader_hists, hists);
|
|
|
|
hists__link(leader_hists, hists);
|
|
|
|
}
|
2011-03-06 08:40:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (nr_samples == 0) {
|
2012-05-29 12:22:57 +08:00
|
|
|
ui__error("The %s file has no samples!\n", session->filename);
|
2013-06-25 19:54:13 +08:00
|
|
|
return 0;
|
2010-03-05 23:51:09 +08:00
|
|
|
}
|
|
|
|
|
2013-01-22 17:09:32 +08:00
|
|
|
list_for_each_entry(pos, &session->evlist->entries, node)
|
|
|
|
hists__output_resort(&pos->hists);
|
|
|
|
|
2011-10-06 06:11:32 +08:00
|
|
|
if (use_browser > 0) {
|
2012-03-20 02:13:29 +08:00
|
|
|
if (use_browser == 1) {
|
2013-02-03 14:38:21 +08:00
|
|
|
ret = perf_evlist__tui_browse_hists(session->evlist,
|
2013-05-14 10:09:04 +08:00
|
|
|
help, NULL,
|
|
|
|
rep->min_percent,
|
2013-02-03 14:38:21 +08:00
|
|
|
&session->header.env);
|
|
|
|
/*
|
|
|
|
* Usually "ret" is the last pressed key, and we only
|
|
|
|
* care if the key notifies us to switch data file.
|
|
|
|
*/
|
|
|
|
if (ret != K_SWITCH_INPUT_DATA)
|
|
|
|
ret = 0;
|
|
|
|
|
2012-03-20 02:13:29 +08:00
|
|
|
} else if (use_browser == 2) {
|
|
|
|
perf_evlist__gtk_browse_hists(session->evlist, help,
|
2013-05-14 10:09:04 +08:00
|
|
|
NULL, rep->min_percent);
|
2012-03-20 02:13:29 +08:00
|
|
|
}
|
2011-10-06 06:11:32 +08:00
|
|
|
} else
|
2011-11-25 18:19:45 +08:00
|
|
|
perf_evlist__tty_browse_hists(session->evlist, rep, help);
|
2009-12-16 22:27:10 +08:00
|
|
|
|
2009-10-07 18:47:31 +08:00
|
|
|
return ret;
|
2009-05-18 23:45:42 +08:00
|
|
|
}
|
|
|
|
|
2009-07-02 23:58:21 +08:00
|
|
|
static int
|
2011-11-25 18:19:45 +08:00
|
|
|
parse_callchain_opt(const struct option *opt, const char *arg, int unset)
|
2009-07-02 23:58:21 +08:00
|
|
|
{
|
2011-11-25 18:19:45 +08:00
|
|
|
struct perf_report *rep = (struct perf_report *)opt->value;
|
2010-05-10 07:28:10 +08:00
|
|
|
char *tok, *tok2;
|
2009-07-03 02:14:33 +08:00
|
|
|
char *endptr;
|
|
|
|
|
2010-01-05 21:54:45 +08:00
|
|
|
/*
|
|
|
|
* --no-call-graph
|
|
|
|
*/
|
|
|
|
if (unset) {
|
2011-11-17 22:19:04 +08:00
|
|
|
rep->dont_use_callchains = true;
|
2010-01-05 21:54:45 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-16 06:04:42 +08:00
|
|
|
symbol_conf.use_callchain = true;
|
2009-07-02 23:58:21 +08:00
|
|
|
|
|
|
|
if (!arg)
|
|
|
|
return 0;
|
|
|
|
|
2009-07-03 02:14:33 +08:00
|
|
|
tok = strtok((char *)arg, ",");
|
|
|
|
if (!tok)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* get the output mode */
|
|
|
|
if (!strncmp(tok, "graph", strlen(arg)))
|
2009-07-05 13:39:21 +08:00
|
|
|
callchain_param.mode = CHAIN_GRAPH_ABS;
|
2009-07-02 23:58:21 +08:00
|
|
|
|
2009-07-03 02:14:33 +08:00
|
|
|
else if (!strncmp(tok, "flat", strlen(arg)))
|
2009-07-05 13:39:21 +08:00
|
|
|
callchain_param.mode = CHAIN_FLAT;
|
|
|
|
|
|
|
|
else if (!strncmp(tok, "fractal", strlen(arg)))
|
|
|
|
callchain_param.mode = CHAIN_GRAPH_REL;
|
|
|
|
|
2009-08-08 08:16:24 +08:00
|
|
|
else if (!strncmp(tok, "none", strlen(arg))) {
|
|
|
|
callchain_param.mode = CHAIN_NONE;
|
2010-01-22 09:47:50 +08:00
|
|
|
symbol_conf.use_callchain = false;
|
2009-08-08 08:16:24 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-02 23:58:21 +08:00
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
|
2009-07-03 02:14:33 +08:00
|
|
|
/* get the min percentage */
|
|
|
|
tok = strtok(NULL, ",");
|
|
|
|
if (!tok)
|
2009-07-05 13:39:21 +08:00
|
|
|
goto setup;
|
2009-07-03 02:14:33 +08:00
|
|
|
|
2009-07-05 13:39:21 +08:00
|
|
|
callchain_param.min_percent = strtod(tok, &endptr);
|
2009-07-03 02:14:33 +08:00
|
|
|
if (tok == endptr)
|
|
|
|
return -1;
|
|
|
|
|
2011-06-07 23:49:46 +08:00
|
|
|
/* get the print limit */
|
|
|
|
tok2 = strtok(NULL, ",");
|
|
|
|
if (!tok2)
|
|
|
|
goto setup;
|
|
|
|
|
|
|
|
if (tok2[0] != 'c') {
|
2011-12-12 23:16:50 +08:00
|
|
|
callchain_param.print_limit = strtoul(tok2, &endptr, 0);
|
2011-06-07 23:49:46 +08:00
|
|
|
tok2 = strtok(NULL, ",");
|
|
|
|
if (!tok2)
|
|
|
|
goto setup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get the call chain order */
|
2013-07-19 06:33:57 +08:00
|
|
|
if (!strncmp(tok2, "caller", strlen("caller")))
|
2011-06-07 23:49:46 +08:00
|
|
|
callchain_param.order = ORDER_CALLER;
|
2013-07-19 06:33:57 +08:00
|
|
|
else if (!strncmp(tok2, "callee", strlen("callee")))
|
2011-06-07 23:49:46 +08:00
|
|
|
callchain_param.order = ORDER_CALLEE;
|
|
|
|
else
|
|
|
|
return -1;
|
2013-07-19 06:33:57 +08:00
|
|
|
|
|
|
|
/* Get the sort key */
|
|
|
|
tok2 = strtok(NULL, ",");
|
|
|
|
if (!tok2)
|
|
|
|
goto setup;
|
|
|
|
if (!strncmp(tok2, "function", strlen("function")))
|
|
|
|
callchain_param.key = CCKEY_FUNCTION;
|
|
|
|
else if (!strncmp(tok2, "address", strlen("address")))
|
|
|
|
callchain_param.key = CCKEY_ADDRESS;
|
|
|
|
else
|
|
|
|
return -1;
|
2009-07-05 13:39:21 +08:00
|
|
|
setup:
|
2011-01-14 11:52:00 +08:00
|
|
|
if (callchain_register_param(&callchain_param) < 0) {
|
2009-07-05 13:39:21 +08:00
|
|
|
fprintf(stderr, "Can't register callchain params\n");
|
|
|
|
return -1;
|
|
|
|
}
|
2009-07-02 23:58:21 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-07 13:48:05 +08:00
|
|
|
int
|
|
|
|
report_parse_ignore_callees_opt(const struct option *opt __maybe_unused,
|
|
|
|
const char *arg, int unset __maybe_unused)
|
|
|
|
{
|
|
|
|
if (arg) {
|
|
|
|
int err = regcomp(&ignore_callees_regex, arg, REG_EXTENDED);
|
|
|
|
if (err) {
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
regerror(err, &ignore_callees_regex, buf, sizeof(buf));
|
|
|
|
pr_err("Invalid --ignore-callees regex: %s\n%s", arg, buf);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
have_ignore_callees = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-03-09 06:47:47 +08:00
|
|
|
static int
|
2012-09-11 06:15:03 +08:00
|
|
|
parse_branch_mode(const struct option *opt __maybe_unused,
|
|
|
|
const char *str __maybe_unused, int unset)
|
2012-03-09 06:47:47 +08:00
|
|
|
{
|
2013-04-01 19:35:20 +08:00
|
|
|
int *branch_mode = opt->value;
|
|
|
|
|
|
|
|
*branch_mode = !unset;
|
2012-03-09 06:47:47 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-05-14 10:09:04 +08:00
|
|
|
static int
|
|
|
|
parse_percent_limit(const struct option *opt, const char *str,
|
|
|
|
int unset __maybe_unused)
|
|
|
|
{
|
|
|
|
struct perf_report *rep = opt->value;
|
|
|
|
|
|
|
|
rep->min_percent = strtof(str, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-09-11 06:15:03 +08:00
|
|
|
int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
2011-11-25 18:19:45 +08:00
|
|
|
{
|
2012-03-09 06:47:47 +08:00
|
|
|
struct perf_session *session;
|
2011-12-07 17:02:54 +08:00
|
|
|
struct stat st;
|
2012-03-09 06:47:47 +08:00
|
|
|
bool has_br_stack = false;
|
2013-04-01 19:35:20 +08:00
|
|
|
int branch_mode = -1;
|
2012-03-09 06:47:47 +08:00
|
|
|
int ret = -1;
|
2011-11-25 18:19:45 +08:00
|
|
|
char callchain_default_opt[] = "fractal,0.5,callee";
|
|
|
|
const char * const report_usage[] = {
|
2011-12-12 23:16:56 +08:00
|
|
|
"perf report [<options>]",
|
2011-11-25 18:19:45 +08:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
struct perf_report report = {
|
2011-11-28 18:30:20 +08:00
|
|
|
.tool = {
|
2011-11-25 18:19:45 +08:00
|
|
|
.sample = process_sample_event,
|
|
|
|
.mmap = perf_event__process_mmap,
|
|
|
|
.comm = perf_event__process_comm,
|
2012-10-07 02:44:59 +08:00
|
|
|
.exit = perf_event__process_exit,
|
|
|
|
.fork = perf_event__process_fork,
|
2011-11-25 18:19:45 +08:00
|
|
|
.lost = perf_event__process_lost,
|
|
|
|
.read = process_read_event,
|
|
|
|
.attr = perf_event__process_attr,
|
|
|
|
.tracing_data = perf_event__process_tracing_data,
|
|
|
|
.build_id = perf_event__process_build_id,
|
|
|
|
.ordered_samples = true,
|
|
|
|
.ordering_requires_timestamps = true,
|
|
|
|
},
|
|
|
|
.pretty_printing_style = "normal",
|
|
|
|
};
|
|
|
|
const struct option options[] = {
|
2012-10-30 11:56:02 +08:00
|
|
|
OPT_STRING('i', "input", &input_name, "file",
|
2009-05-26 15:17:18 +08:00
|
|
|
"input file name"),
|
2010-04-13 16:37:33 +08:00
|
|
|
OPT_INCR('v', "verbose", &verbose,
|
2009-05-27 06:46:14 +08:00
|
|
|
"be more verbose (show symbol address, etc)"),
|
2009-05-27 00:48:58 +08:00
|
|
|
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
|
|
|
|
"dump raw trace in ASCII"),
|
2009-11-24 22:05:15 +08:00
|
|
|
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
|
|
|
|
"file", "vmlinux pathname"),
|
2010-12-08 10:39:46 +08:00
|
|
|
OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
|
|
|
|
"file", "kallsyms pathname"),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_BOOLEAN('f', "force", &report.force, "don't complain, do it"),
|
2009-11-24 22:05:15 +08:00
|
|
|
OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
|
2009-07-02 14:09:46 +08:00
|
|
|
"load module symbols - WARNING: use only with -k and LIVE kernel"),
|
2009-12-16 06:04:42 +08:00
|
|
|
OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
|
2009-07-11 23:18:37 +08:00
|
|
|
"Show a column with the number of samples"),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_BOOLEAN('T', "threads", &report.show_threads,
|
2009-08-07 19:55:24 +08:00
|
|
|
"Show per-thread event counters"),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_STRING(0, "pretty", &report.pretty_printing_style, "key",
|
2009-08-10 21:26:32 +08:00
|
|
|
"pretty printing style key: normal raw"),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_BOOLEAN(0, "tui", &report.use_tui, "Use the TUI interface"),
|
2012-03-20 02:13:29 +08:00
|
|
|
OPT_BOOLEAN(0, "gtk", &report.use_gtk, "Use the GTK2 interface"),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_BOOLEAN(0, "stdio", &report.use_stdio,
|
|
|
|
"Use the stdio interface"),
|
2009-05-28 16:52:00 +08:00
|
|
|
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
|
2012-12-27 17:11:47 +08:00
|
|
|
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
|
2013-01-24 23:10:29 +08:00
|
|
|
" dso_to, dso_from, symbol_to, symbol_from, mispredict,"
|
2013-01-24 23:10:36 +08:00
|
|
|
" weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, "
|
|
|
|
"snoop, locked"),
|
2010-04-19 13:32:50 +08:00
|
|
|
OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
|
|
|
|
"Show sample percentage for different cpu modes"),
|
2009-06-18 13:01:03 +08:00
|
|
|
OPT_STRING('p', "parent", &parent_pattern, "regex",
|
|
|
|
"regex filter to identify parent, see: '--sort parent'"),
|
2009-12-16 06:04:42 +08:00
|
|
|
OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
|
2009-06-18 20:32:19 +08:00
|
|
|
"Only display entries with parent-match"),
|
2011-12-12 23:16:50 +08:00
|
|
|
OPT_CALLBACK_DEFAULT('g', "call-graph", &report, "output_type,min_percent[,print_limit],call_order",
|
2013-07-19 06:33:57 +08:00
|
|
|
"Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold, optional print limit, callchain order, key (function or address). "
|
|
|
|
"Default: fractal,0.5,callee,function", &parse_callchain_opt, callchain_default_opt),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_BOOLEAN('G', "inverted", &report.inverted_callchain,
|
|
|
|
"alias for inverted call graph"),
|
2012-12-07 13:48:05 +08:00
|
|
|
OPT_CALLBACK(0, "ignore-callees", NULL, "regex",
|
|
|
|
"ignore callees of these functions in call graphs",
|
|
|
|
report_parse_ignore_callees_opt),
|
2009-12-16 06:04:40 +08:00
|
|
|
OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
|
2009-07-01 06:01:20 +08:00
|
|
|
"only consider symbols in these dsos"),
|
2011-11-14 02:30:08 +08:00
|
|
|
OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
|
2009-07-01 06:01:21 +08:00
|
|
|
"only consider symbols in these comms"),
|
2009-12-16 06:04:40 +08:00
|
|
|
OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
|
2009-07-01 06:01:22 +08:00
|
|
|
"only consider these symbols"),
|
2012-03-16 16:50:54 +08:00
|
|
|
OPT_STRING(0, "symbol-filter", &report.symbol_filter_str, "filter",
|
|
|
|
"only show symbols that (partially) match with this filter"),
|
2009-12-16 06:04:40 +08:00
|
|
|
OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
|
2009-07-11 09:47:28 +08:00
|
|
|
"width[,width...]",
|
|
|
|
"don't try to adjust column width, use these fixed values"),
|
2009-12-16 06:04:41 +08:00
|
|
|
OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
|
2009-07-11 09:47:28 +08:00
|
|
|
"separator for columns, no spaces will be added between "
|
|
|
|
"columns '.' is reserved."),
|
2011-11-17 22:19:04 +08:00
|
|
|
OPT_BOOLEAN('U', "hide-unresolved", &report.hide_unresolved,
|
2009-12-29 08:48:34 +08:00
|
|
|
"Only display entries resolved to a symbol"),
|
2010-12-10 04:27:07 +08:00
|
|
|
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
|
|
|
|
"Look for files with symbols relative to this directory"),
|
2011-11-14 02:30:08 +08:00
|
|
|
OPT_STRING('C', "cpu", &report.cpu_list, "cpu",
|
2011-11-17 22:19:04 +08:00
|
|
|
"list of cpus to profile"),
|
|
|
|
OPT_BOOLEAN('I', "show-info", &report.show_full_info,
|
perf tools: Make perf.data more self-descriptive (v8)
The goal of this patch is to include more information about the host
environment into the perf.data so it is more self-descriptive. Overtime,
profiles are captured on various machines and it becomes hard to track
what was recorded, on what machine and when.
This patch provides a way to solve this by extending the perf.data file
with basic information about the host machine. To add those extensions,
we leverage the feature bits capabilities of the perf.data format. The
change is backward compatible with existing perf.data files.
We define the following useful new extensions:
- HEADER_HOSTNAME: the hostname
- HEADER_OSRELEASE: the kernel release number
- HEADER_ARCH: the hw architecture
- HEADER_CPUDESC: generic CPU description
- HEADER_NRCPUS: number of online/avail cpus
- HEADER_CMDLINE: perf command line
- HEADER_VERSION: perf version
- HEADER_TOPOLOGY: cpu topology
- HEADER_EVENT_DESC: full event description (attrs)
- HEADER_CPUID: easy-to-parse low level CPU identication
The small granularity for the entries is to make it easier to extend
without breaking backward compatiblity. Many entries are provided as
ASCII strings.
Perf report/script have been modified to print the basic information as
easy-to-parse ASCII strings. Extended information about CPU and NUMA
topology may be requested with the -I option.
Thanks to David Ahern for reviewing and testing the many versions of
this patch.
$ perf report --stdio
# ========
# captured on : Mon Sep 26 15:22:14 2011
# hostname : quad
# os release : 3.1.0-rc4-tip
# perf version : 3.1.0-rc4
# arch : x86_64
# nrcpus online : 4
# nrcpus avail : 4
# cpudesc : Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 8105360 kB
# cmdline : /home/eranian/perfmon/official/tip/build/tools/perf/perf record date
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 29, 30, 31,
# HEADER_CPU_TOPOLOGY info available, use -I to display
# HEADER_NUMA_TOPOLOGY info available, use -I to display
# ========
#
...
$ perf report --stdio -I
# ========
# captured on : Mon Sep 26 15:22:14 2011
# hostname : quad
# os release : 3.1.0-rc4-tip
# perf version : 3.1.0-rc4
# arch : x86_64
# nrcpus online : 4
# nrcpus avail : 4
# cpudesc : Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz
# cpuid : GenuineIntel,6,15,11
# total memory : 8105360 kB
# cmdline : /home/eranian/perfmon/official/tip/build/tools/perf/perf record date
# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 29, 30, 31,
# sibling cores : 0-3
# sibling threads : 0
# sibling threads : 1
# sibling threads : 2
# sibling threads : 3
# node0 meminfo : total = 8320608 kB, free = 7571024 kB
# node0 cpu list : 0-3
# ========
#
...
Reviewed-by: David Ahern <dsahern@gmail.com>
Tested-by: David Ahern <dsahern@gmail.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Robert Richter <robert.richter@amd.com>
Cc: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/20110930134040.GA5575@quad
Signed-off-by: Stephane Eranian <eranian@google.com>
[ committer notes: Use --show-info in the tools as was in the docs, rename
perf_header_fprintf_info to perf_file_section__fprintf_info, fixup
conflict with f69b64f7 "perf: Support setting the disassembler style" ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2011-09-30 21:40:40 +08:00
|
|
|
"Display extended information about perf.data file"),
|
2011-10-06 23:48:31 +08:00
|
|
|
OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
|
|
|
|
"Interleave source code with assembly code (default)"),
|
|
|
|
OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
|
|
|
|
"Display raw encoding of assembly instructions (default)"),
|
2011-09-16 05:31:41 +08:00
|
|
|
OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
|
|
|
|
"Specify disassembler style (e.g. -M intel for intel syntax)"),
|
2011-10-06 03:10:06 +08:00
|
|
|
OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
|
|
|
|
"Show a column with the sum of periods"),
|
2013-01-22 17:09:45 +08:00
|
|
|
OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
|
|
|
|
"Show event group information together"),
|
2013-04-01 19:35:20 +08:00
|
|
|
OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
|
2012-03-09 06:47:47 +08:00
|
|
|
"use branch records for histogram filling", parse_branch_mode),
|
2012-09-04 18:32:30 +08:00
|
|
|
OPT_STRING(0, "objdump", &objdump_path, "path",
|
|
|
|
"objdump binary to use for disassembly and annotations"),
|
2013-03-25 17:18:18 +08:00
|
|
|
OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
|
|
|
|
"Disable symbol demangling"),
|
2013-01-24 23:10:36 +08:00
|
|
|
OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
|
2013-05-14 10:09:04 +08:00
|
|
|
OPT_CALLBACK(0, "percent-limit", &report, "percent",
|
|
|
|
"Don't show entries under that percent", parse_percent_limit),
|
2009-05-26 15:17:18 +08:00
|
|
|
OPT_END()
|
2011-11-25 18:19:45 +08:00
|
|
|
};
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2013-05-14 10:09:06 +08:00
|
|
|
perf_config(perf_report_config, &report);
|
2013-01-22 17:09:46 +08:00
|
|
|
|
2009-12-16 06:04:40 +08:00
|
|
|
argc = parse_options(argc, argv, options, report_usage, 0);
|
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (report.use_stdio)
|
2010-08-21 21:38:16 +08:00
|
|
|
use_browser = 0;
|
2011-11-17 22:19:04 +08:00
|
|
|
else if (report.use_tui)
|
2010-08-21 21:38:16 +08:00
|
|
|
use_browser = 1;
|
2012-03-20 02:13:29 +08:00
|
|
|
else if (report.use_gtk)
|
|
|
|
use_browser = 2;
|
2010-08-21 21:38:16 +08:00
|
|
|
|
2011-11-17 22:19:04 +08:00
|
|
|
if (report.inverted_callchain)
|
2011-06-07 23:49:46 +08:00
|
|
|
callchain_param.order = ORDER_CALLER;
|
|
|
|
|
2012-10-30 11:56:02 +08:00
|
|
|
if (!input_name || !strlen(input_name)) {
|
2011-12-07 17:02:54 +08:00
|
|
|
if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
|
2012-10-30 11:56:02 +08:00
|
|
|
input_name = "-";
|
2011-12-07 17:02:54 +08:00
|
|
|
else
|
2012-10-30 11:56:02 +08:00
|
|
|
input_name = "perf.data";
|
2011-12-07 17:02:54 +08:00
|
|
|
}
|
2013-02-03 14:38:21 +08:00
|
|
|
|
|
|
|
if (strcmp(input_name, "-") != 0)
|
|
|
|
setup_browser(true);
|
|
|
|
else {
|
|
|
|
use_browser = 0;
|
|
|
|
perf_hpp__init();
|
|
|
|
}
|
|
|
|
|
|
|
|
repeat:
|
2012-10-30 11:56:02 +08:00
|
|
|
session = perf_session__new(input_name, O_RDONLY,
|
2012-03-09 06:47:47 +08:00
|
|
|
report.force, false, &report.tool);
|
|
|
|
if (session == NULL)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
report.session = session;
|
|
|
|
|
|
|
|
has_br_stack = perf_header__has_feat(&session->header,
|
|
|
|
HEADER_BRANCH_STACK);
|
2011-12-07 17:02:54 +08:00
|
|
|
|
2013-04-01 19:35:20 +08:00
|
|
|
if (branch_mode == -1 && has_br_stack)
|
|
|
|
sort__mode = SORT_MODE__BRANCH;
|
2012-03-09 06:47:47 +08:00
|
|
|
|
2013-04-01 19:35:20 +08:00
|
|
|
/* sort__mode could be NORMAL if --no-branch-stack */
|
|
|
|
if (sort__mode == SORT_MODE__BRANCH) {
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
/*
|
2012-03-09 06:47:48 +08:00
|
|
|
* if no sort_order is provided, then specify
|
|
|
|
* branch-mode specific order
|
perf report: Add support for taken branch sampling
This patch adds support for taken branch sampling, i.e, the
PERF_SAMPLE_BRANCH_STACK feature to perf report. In other
words, to display histograms based on taken branches rather
than executed instructions addresses.
The new option is called -b and it takes no argument. To
generate meaningful output, the perf.data must have been
obtained using perf record -b xxx ... where xxx is a branch
filter option.
The output shows symbols, modules, sorted by 'who branches
where' the most often. The percentages reported in the first
column refer to the total number of branches captured and
not the usual number of samples.
Here is a quick example.
Here branchy is simple test program which looks as follows:
void f2(void)
{}
void f3(void)
{}
void f1(unsigned long n)
{
if (n & 1UL)
f2();
else
f3();
}
int main(void)
{
unsigned long i;
for (i=0; i < N; i++)
f1(i);
return 0;
}
Here is the output captured on Nehalem, if we are
only interested in user level function calls.
$ perf record -b any_call,u -e cycles:u branchy
$ perf report -b --sort=symbol
52.34% [.] main [.] f1
24.04% [.] f1 [.] f3
23.60% [.] f1 [.] f2
0.01% [k] _IO_new_file_xsputn [k] _IO_file_overflow
0.01% [k] _IO_vfprintf_internal [k] _IO_new_file_xsputn
0.01% [k] _IO_vfprintf_internal [k] strchrnul
0.01% [k] __printf [k] _IO_vfprintf_internal
0.01% [k] main [k] __printf
About half (52%) of the call branches captured are from main()
-> f1(). The second half (24%+23%) is split in two equal shares
between f1() -> f2(), f1() ->f3(). The output is as expected
given the code.
It should be noted, that using -b in perf record does not
eliminate information in the perf.data file. Consequently, a
typical profile can also be obtained by perf report by simply
not using its -b option.
It is possible to sort on branch related columns:
- dso_from, symbol_from
- dso_to, symbol_to
- mispredict
Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov>
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-14-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2012-02-10 06:21:03 +08:00
|
|
|
*/
|
|
|
|
if (sort_order == default_sort_order)
|
|
|
|
sort_order = "comm,dso_from,symbol_from,"
|
|
|
|
"dso_to,symbol_to";
|
|
|
|
|
2012-03-09 06:47:48 +08:00
|
|
|
}
|
2013-01-24 23:10:36 +08:00
|
|
|
if (report.mem_mode) {
|
2013-04-01 19:35:20 +08:00
|
|
|
if (sort__mode == SORT_MODE__BRANCH) {
|
2013-01-24 23:10:36 +08:00
|
|
|
fprintf(stderr, "branch and mem mode incompatible\n");
|
|
|
|
goto error;
|
|
|
|
}
|
2013-04-03 20:26:11 +08:00
|
|
|
sort__mode = SORT_MODE__MEMORY;
|
|
|
|
|
2013-01-24 23:10:36 +08:00
|
|
|
/*
|
|
|
|
* if no sort_order is provided, then specify
|
|
|
|
* branch-mode specific order
|
|
|
|
*/
|
|
|
|
if (sort_order == default_sort_order)
|
|
|
|
sort_order = "local_weight,mem,sym,dso,symbol_daddr,dso_daddr,snoop,tlb,locked";
|
|
|
|
}
|
2012-03-09 06:47:48 +08:00
|
|
|
|
2013-02-06 13:57:16 +08:00
|
|
|
if (setup_sorting() < 0)
|
|
|
|
usage_with_options(report_usage, options);
|
2012-09-14 16:35:28 +08:00
|
|
|
|
2010-05-12 10:18:06 +08:00
|
|
|
/*
|
2013-03-28 22:34:10 +08:00
|
|
|
* Only in the TUI browser we are doing integrated annotation,
|
2010-05-12 10:18:06 +08:00
|
|
|
* so don't allocate extra space that won't be used in the stdio
|
|
|
|
* implementation.
|
|
|
|
*/
|
2012-09-14 16:35:28 +08:00
|
|
|
if (use_browser == 1 && sort__has_sym) {
|
2011-02-04 19:45:46 +08:00
|
|
|
symbol_conf.priv_size = sizeof(struct annotation);
|
2013-08-08 19:32:22 +08:00
|
|
|
machines__set_symbol_filter(&session->machines,
|
|
|
|
symbol__annotate_init);
|
2010-08-06 06:28:27 +08:00
|
|
|
/*
|
|
|
|
* For searching by name on the "Browse map details".
|
|
|
|
* providing it only in verbose mode not to bloat too
|
|
|
|
* much struct symbol.
|
|
|
|
*/
|
|
|
|
if (verbose) {
|
|
|
|
/*
|
|
|
|
* XXX: Need to provide a less kludgy way to ask for
|
|
|
|
* more space per symbol, the u32 is for the index on
|
|
|
|
* the ui browser.
|
|
|
|
* See symbol__browser_index.
|
|
|
|
*/
|
|
|
|
symbol_conf.priv_size += sizeof(u32);
|
|
|
|
symbol_conf.sort_by_name = true;
|
|
|
|
}
|
|
|
|
}
|
2009-12-16 06:04:40 +08:00
|
|
|
|
2009-12-16 06:04:39 +08:00
|
|
|
if (symbol__init() < 0)
|
2012-03-09 06:47:47 +08:00
|
|
|
goto error;
|
2009-05-26 15:17:18 +08:00
|
|
|
|
2009-07-11 23:18:35 +08:00
|
|
|
if (parent_pattern != default_parent_pattern) {
|
2010-04-02 23:30:57 +08:00
|
|
|
if (sort_dimension__add("parent") < 0)
|
2012-03-09 06:47:47 +08:00
|
|
|
goto error;
|
2013-06-10 14:21:21 +08:00
|
|
|
}
|
2009-06-18 20:32:19 +08:00
|
|
|
|
2012-03-16 16:50:55 +08:00
|
|
|
if (argc) {
|
|
|
|
/*
|
|
|
|
* Special case: if there's an argument left then assume that
|
|
|
|
* it's a symbol filter:
|
|
|
|
*/
|
|
|
|
if (argc > 1)
|
|
|
|
usage_with_options(report_usage, options);
|
|
|
|
|
|
|
|
report.symbol_filter_str = argv[0];
|
|
|
|
}
|
2009-06-04 22:24:37 +08:00
|
|
|
|
2013-04-03 20:26:19 +08:00
|
|
|
sort__setup_elide(stdout);
|
2009-07-01 06:01:20 +08:00
|
|
|
|
2012-03-09 06:47:47 +08:00
|
|
|
ret = __cmd_report(&report);
|
2013-02-03 14:38:21 +08:00
|
|
|
if (ret == K_SWITCH_INPUT_DATA) {
|
|
|
|
perf_session__delete(session);
|
|
|
|
goto repeat;
|
|
|
|
} else
|
|
|
|
ret = 0;
|
|
|
|
|
2012-03-09 06:47:47 +08:00
|
|
|
error:
|
|
|
|
perf_session__delete(session);
|
|
|
|
return ret;
|
2009-05-26 15:17:18 +08:00
|
|
|
}
|