Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 288727
b: refs/heads/master
c: b50311d
h: refs/heads/master
i:
  288725: e127516
  288723: 1038616
  288719: c15306a
v: v3
  • Loading branch information
Roberto Agostino Vitillo authored and Ingo Molnar committed Mar 9, 2012
1 parent c98643e commit ddd211b
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 10 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bdfebd848f2a14e639031a0b0e61d7c7ee5e5fd2
refs/heads/master: b50311dc2ac1c04ad19163c2359910b25e16caf6
7 changes: 7 additions & 0 deletions trunk/tools/perf/Documentation/perf-report.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,13 @@ OPTIONS
information which may be very large and thus may clutter the display.
It currently includes: cpu and numa topology of the host system.

-b::
--branch-stack::
Use the addresses of sampled taken branches instead of the instruction
address to build the histograms. To generate meaningful output, the
perf.data file must have been obtained using perf record -b xxx where
xxx is a branch filter option.

SEE ALSO
--------
linkperf:perf-stat[1], linkperf:perf-annotate[1]
107 changes: 98 additions & 9 deletions trunk/tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,50 @@ struct perf_report {
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
};

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;
struct branch_info *bi;

if ((sort__has_parent || symbol_conf.use_callchain)
&& sample->callchain) {
err = machine__resolve_callchain(machine, evsel, al->thread,
sample->callchain, &parent);
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;
/*
* 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,
&bi[i], 1);
if (he) {
evsel->hists.stats.total_period += 1;
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
} else
return -ENOMEM;
}
return err;
}

static int perf_evsel__add_hist_entry(struct perf_evsel *evsel,
struct addr_location *al,
struct perf_sample *sample,
Expand Down Expand Up @@ -126,14 +170,21 @@ static int process_sample_event(struct perf_tool *tool,
if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
return 0;

if (al.map != NULL)
al.map->dso->hit = 1;
if (sort__branch_mode) {
if (perf_report__add_branch_hist_entry(tool, &al, sample,
evsel, machine)) {
pr_debug("problem adding lbr entry, skipping event\n");
return -1;
}
} else {
if (al.map != NULL)
al.map->dso->hit = 1;

if (perf_evsel__add_hist_entry(evsel, &al, sample, machine)) {
pr_debug("problem incrementing symbol period, skipping event\n");
return -1;
if (perf_evsel__add_hist_entry(evsel, &al, sample, machine)) {
pr_debug("problem incrementing symbol period, skipping event\n");
return -1;
}
}

return 0;
}

Expand Down Expand Up @@ -188,6 +239,15 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
}
}

if (sort__branch_mode) {
if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) {
fprintf(stderr, "selected -b but no branch data."
" Did you call perf record without"
" -b?\n");
return -1;
}
}

return 0;
}

Expand Down Expand Up @@ -477,7 +537,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
OPT_BOOLEAN(0, "stdio", &report.use_stdio,
"Use the stdio interface"),
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
"sort by key(s): pid, comm, dso, symbol, parent"),
"sort by key(s): pid, comm, dso, symbol, parent, dso_to,"
" dso_from, symbol_to, symbol_from, mispredict"),
OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
"Show sample percentage for different cpu modes"),
OPT_STRING('p', "parent", &parent_pattern, "regex",
Expand Down Expand Up @@ -517,6 +578,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
"Specify disassembler style (e.g. -M intel for intel syntax)"),
OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
"Show a column with the sum of periods"),
OPT_BOOLEAN('b', "branch-stack", &sort__branch_mode,
"use branch records for histogram filling"),
OPT_END()
};

Expand All @@ -537,10 +600,36 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
report.input_name = "perf.data";
}

if (strcmp(report.input_name, "-") != 0)
if (sort__branch_mode) {
if (use_browser)
fprintf(stderr, "Warning: TUI interface not supported"
" in branch mode\n");
if (symbol_conf.dso_list_str != NULL)
fprintf(stderr, "Warning: dso filtering not supported"
" in branch mode\n");
if (symbol_conf.sym_list_str != NULL)
fprintf(stderr, "Warning: symbol filtering not"
" supported in branch mode\n");

report.use_stdio = true;
use_browser = 0;
setup_browser(true);
else
symbol_conf.dso_list_str = NULL;
symbol_conf.sym_list_str = NULL;

/*
* if no sort_order is provided, then specify branch-mode
* specific order
*/
if (sort_order == default_sort_order)
sort_order = "comm,dso_from,symbol_from,"
"dso_to,symbol_to";

} else if (strcmp(report.input_name, "-") != 0) {
setup_browser(true);
} else {
use_browser = 0;
}

/*
* Only in the newt browser we are doing integrated annotation,
Expand Down

0 comments on commit ddd211b

Please sign in to comment.