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]".
|
entries are displayed as "[other]".
|
||||||
- cpu: cpu number the task ran at the time of sample
|
- cpu: cpu number the task ran at the time of sample
|
||||||
- srcline: filename and line number executed at the time of sample. The
|
- 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.
|
By default, comm, dso and symbol keys are used.
|
||||||
(i.e. --sort comm,dso,symbol)
|
(i.e. --sort comm,dso,symbol)
|
||||||
@ -85,6 +85,8 @@ OPTIONS
|
|||||||
- symbol_from: name of function branched from
|
- symbol_from: name of function branched from
|
||||||
- symbol_to: name of function branched to
|
- symbol_to: name of function branched to
|
||||||
- mispredict: "N" for predicted branch, "Y" for mispredicted branch
|
- 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 default sort keys are changed to comm, dso_from, symbol_from, dso_to
|
||||||
and symbol_to, see '--branch-stack'.
|
and symbol_to, see '--branch-stack'.
|
||||||
|
@ -112,7 +112,8 @@ Default is to monitor all CPUS.
|
|||||||
|
|
||||||
-s::
|
-s::
|
||||||
--sort::
|
--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::
|
-n::
|
||||||
--show-nr-samples::
|
--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,"
|
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline,"
|
||||||
" dso_to, dso_from, symbol_to, symbol_from, mispredict,"
|
" dso_to, dso_from, symbol_to, symbol_from, mispredict,"
|
||||||
" weight, local_weight, mem, symbol_daddr, dso_daddr, tlb, "
|
" 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,
|
OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
|
||||||
"Show sample percentage for different cpu modes"),
|
"Show sample percentage for different cpu modes"),
|
||||||
OPT_STRING('p', "parent", &parent_pattern, "regex",
|
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,
|
OPT_INCR('v', "verbose", &verbose,
|
||||||
"be more verbose (show counter open errors, etc)"),
|
"be more verbose (show counter open errors, etc)"),
|
||||||
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
|
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,
|
OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
|
||||||
"Show a column with the number of samples"),
|
"Show a column with the number of samples"),
|
||||||
OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts,
|
OPT_CALLBACK_DEFAULT('G', "call-graph", &top.record_opts,
|
||||||
|
@ -182,7 +182,9 @@ struct ip_callchain {
|
|||||||
struct branch_flags {
|
struct branch_flags {
|
||||||
u64 mispred:1;
|
u64 mispred:1;
|
||||||
u64 predicted:1;
|
u64 predicted:1;
|
||||||
u64 reserved:62;
|
u64 in_tx:1;
|
||||||
|
u64 abort:1;
|
||||||
|
u64 reserved:60;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct branch_entry {
|
struct branch_entry {
|
||||||
|
@ -45,6 +45,8 @@ enum hist_column {
|
|||||||
HISTC_CPU,
|
HISTC_CPU,
|
||||||
HISTC_SRCLINE,
|
HISTC_SRCLINE,
|
||||||
HISTC_MISPREDICT,
|
HISTC_MISPREDICT,
|
||||||
|
HISTC_IN_TX,
|
||||||
|
HISTC_ABORT,
|
||||||
HISTC_SYMBOL_FROM,
|
HISTC_SYMBOL_FROM,
|
||||||
HISTC_SYMBOL_TO,
|
HISTC_SYMBOL_TO,
|
||||||
HISTC_DSO_FROM,
|
HISTC_DSO_FROM,
|
||||||
|
@ -858,6 +858,55 @@ struct sort_entry sort_mem_snoop = {
|
|||||||
.se_width_idx = HISTC_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 {
|
struct sort_dimension {
|
||||||
const char *name;
|
const char *name;
|
||||||
struct sort_entry *entry;
|
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_FROM, "symbol_from", sort_sym_from),
|
||||||
DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
|
DIM(SORT_SYM_TO, "symbol_to", sort_sym_to),
|
||||||
DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
|
DIM(SORT_MISPREDICT, "mispredict", sort_mispredict),
|
||||||
|
DIM(SORT_IN_TX, "in_tx", sort_in_tx),
|
||||||
|
DIM(SORT_ABORT, "abort", sort_abort),
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef DIM
|
#undef DIM
|
||||||
|
@ -153,6 +153,8 @@ enum sort_type {
|
|||||||
SORT_SYM_FROM,
|
SORT_SYM_FROM,
|
||||||
SORT_SYM_TO,
|
SORT_SYM_TO,
|
||||||
SORT_MISPREDICT,
|
SORT_MISPREDICT,
|
||||||
|
SORT_ABORT,
|
||||||
|
SORT_IN_TX,
|
||||||
|
|
||||||
/* memory mode specific sort keys */
|
/* memory mode specific sort keys */
|
||||||
__SORT_MEMORY_MODE,
|
__SORT_MEMORY_MODE,
|
||||||
|
Loading…
Reference in New Issue
Block a user