tools/perf: Support sorting by in_tx or abort branch flags
Extend the perf branch sorting code to support sorting by in_tx or abort_tx qualifiers. Also print out those qualifiers. This also fixes up some of the existing sort key documentation. We do not support no_tx here, because it's simply not showing the in_tx flag. Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1379688044-14173-4-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
a405bad5ad
commit
f5d05bcec4
@ -71,7 +71,7 @@ OPTIONS
|
||||
entries are displayed as "[other]".
|
||||
- cpu: cpu number the task ran at the time of sample
|
||||
- srcline: filename and line number executed at the time of sample. The
|
||||
DWARF debuggin info must be provided.
|
||||
DWARF debugging info must be provided.
|
||||
|
||||
By default, comm, dso and symbol keys are used.
|
||||
(i.e. --sort comm,dso,symbol)
|
||||
@ -85,6 +85,8 @@ OPTIONS
|
||||
- symbol_from: name of function branched from
|
||||
- symbol_to: name of function branched to
|
||||
- mispredict: "N" for predicted branch, "Y" for mispredicted branch
|
||||
- in_tx: branch in TSX transaction
|
||||
- abort: TSX transaction abort.
|
||||
|
||||
And default sort keys are changed to comm, dso_from, symbol_from, dso_to
|
||||
and symbol_to, see '--branch-stack'.
|
||||
|
@ -112,7 +112,8 @@ Default is to monitor all CPUS.
|
||||
|
||||
-s::
|
||||
--sort::
|
||||
Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight, local_weight.
|
||||
Sort by key(s): pid, comm, dso, symbol, parent, srcline, weight,
|
||||
local_weight, abort, in_tx
|
||||
|
||||
-n::
|
||||
--show-nr-samples::
|
||||
|
@ -787,7 +787,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
|
||||
" dso_to, dso_from, symbol_to, symbol_from, mispredict,"
|
||||
" weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, "
|
||||
"snoop, locked"),
|
||||
"snoop, locked, abort, in_tx"),
|
||||
OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
|
||||
"Show sample percentage for different cpu modes"),
|
||||
OPT_STRING('p', "parent", &parent_pattern, "regex",
|
||||
|
@ -1103,7 +1103,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
OPT_INCR('v', "verbose", &verbose,
|
||||
"be more verbose (show counter open errors, etc)"),
|
||||
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
|
||||
"sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight"),
|
||||
"sort by key(s): pid, comm, dso, symbol, parent, weight, local_weight,"
|
||||
" abort, in_tx"),
|
||||
OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
|
||||
"Show a column with the number of samples"),
|
||||
OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts,
|
||||
|
@ -182,7 +182,9 @@ struct ip_callchain {
|
||||
struct branch_flags {
|
||||
u64 mispred:1;
|
||||
u64 predicted:1;
|
||||
u64 reserved:62;
|
||||
u64 in_tx:1;
|
||||
u64 abort:1;
|
||||
u64 reserved:60;
|
||||
};
|
||||
|
||||
struct branch_entry {
|
||||
|
@ -45,6 +45,8 @@ enum hist_column {
|
||||
HISTC_CPU,
|
||||
HISTC_SRCLINE,
|
||||
HISTC_MISPREDICT,
|
||||
HISTC_IN_TX,
|
||||
HISTC_ABORT,
|
||||
HISTC_SYMBOL_FROM,
|
||||
HISTC_SYMBOL_TO,
|
||||
HISTC_DSO_FROM,
|
||||
|
@ -858,6 +858,55 @@ struct sort_entry sort_mem_snoop = {
|
||||
.se_width_idx = HISTC_MEM_SNOOP,
|
||||
};
|
||||
|
||||
static int64_t
|
||||
sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||
{
|
||||
return left->branch_info->flags.abort !=
|
||||
right->branch_info->flags.abort;
|
||||
}
|
||||
|
||||
static int hist_entry__abort_snprintf(struct hist_entry *self, char *bf,
|
||||
size_t size, unsigned int width)
|
||||
{
|
||||
static const char *out = ".";
|
||||
|
||||
if (self->branch_info->flags.abort)
|
||||
out = "A";
|
||||
return repsep_snprintf(bf, size, "%-*s", width, out);
|
||||
}
|
||||
|
||||
struct sort_entry sort_abort = {
|
||||
.se_header = "Transaction abort",
|
||||
.se_cmp = sort__abort_cmp,
|
||||
.se_snprintf = hist_entry__abort_snprintf,
|
||||
.se_width_idx = HISTC_ABORT,
|
||||
};
|
||||
|
||||
static int64_t
|
||||
sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
|
||||
{
|
||||
return left->branch_info->flags.in_tx !=
|
||||
right->branch_info->flags.in_tx;
|
||||
}
|
||||
|
||||
static int hist_entry__in_tx_snprintf(struct hist_entry *self, char *bf,
|
||||
size_t size, unsigned int width)
|
||||
{
|
||||
static const char *out = ".";
|
||||
|
||||
if (self->branch_info->flags.in_tx)
|
||||
out = "T";
|
||||
|
||||
return repsep_snprintf(bf, size, "%-*s", width, out);
|
||||
}
|
||||
|
||||
struct sort_entry sort_in_tx = {
|
||||
.se_header = "Branch in transaction",
|
||||
.se_cmp = sort__in_tx_cmp,
|
||||
.se_snprintf = hist_entry__in_tx_snprintf,
|
||||
.se_width_idx = HISTC_IN_TX,
|
||||
};
|
||||
|
||||
struct sort_dimension {
|
||||
const char *name;
|
||||
struct sort_entry *entry;
|
||||
@ -888,6 +937,8 @@ static struct sort_dimension bstack_sort_dimensions[] = {
|
||||
DIM(SORT_SYM_FROM, "symbol_from", sort_sym_from),
|
||||
DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
|
||||
DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
|
||||
DIM(SORT_IN_TX, "in_tx", sort_in_tx),
|
||||
DIM(SORT_ABORT, "abort", sort_abort),
|
||||
};
|
||||
|
||||
#undef DIM
|
||||
|
@ -153,6 +153,8 @@ enum sort_type {
|
||||
SORT_SYM_FROM,
|
||||
SORT_SYM_TO,
|
||||
SORT_MISPREDICT,
|
||||
SORT_ABORT,
|
||||
SORT_IN_TX,
|
||||
|
||||
/* memory mode specific sort keys */
|
||||
__SORT_MEMORY_MODE,
|
||||
|
Loading…
Reference in New Issue
Block a user