mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
perf report: Display columns Predicted/Abort/Cycles in --branch-history
The original commit message: " Use current sort mechanism but the real .se_cmp() just returns 0 so that new columns "Predicted", "Abort" and "Cycles" are created in display but actually these keys are not the sort keys. For example: Overhead Source:Line Symbol Shared Object Predicted Abort Cycles ........ ............ ........ ............. ......... ..... ...... 38.25% div.c:45 [.] main div 97.6% 0 3 " Update missed commit from series "perf report: Show branch flags/cycles in --branch-history callgraph view" to apply to current repository so that new columns described above are visible. Link to original series: https://lore.kernel.org/lkml/1477876794-30749-1-git-send-email-yao.jin@linux.intel.com/ Reported-by: Dr. David Alan Gilbert <linux@treblig.org> Suggested-by: Kan Liang <kan.liang@linux.intel.com> Co-developed-by: Jin Yao <yao.jin@linux.intel.com> Signed-off-by: Jin Yao <yao.jin@linux.intel.com> Tested-by: Thomas Falcon <thomas.falcon@intel.com> Signed-off-by: Thomas Falcon <thomas.falcon@intel.com> Link: https://lore.kernel.org/r/20241010184046.203822-1-thomas.falcon@intel.com Signed-off-by: Namhyung Kim <namhyung@kernel.org>
This commit is contained in:
parent
8c25df7af3
commit
48966a5a48
@ -391,6 +391,14 @@ OPTIONS
|
||||
This allows to examine the path the program took to each sample.
|
||||
The data collection must have used -b (or -j) and -g.
|
||||
|
||||
Also show with some branch flags that can be:
|
||||
- Predicted: display the average percentage of predicated branches.
|
||||
(predicated number / total number)
|
||||
- Abort: display the number of tsx aborted branches.
|
||||
- Cycles: cycles in basic block.
|
||||
|
||||
- iterations: display the average number of iterations in callchain list.
|
||||
|
||||
--addr2line=<path>::
|
||||
Path to addr2line binary.
|
||||
|
||||
|
@ -1271,6 +1271,10 @@ static int process_attr(const struct perf_tool *tool __maybe_unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CALLCHAIN_BRANCH_SORT_ORDER \
|
||||
"srcline,symbol,dso,callchain_branch_predicted," \
|
||||
"callchain_branch_abort,callchain_branch_cycles"
|
||||
|
||||
int cmd_report(int argc, const char **argv)
|
||||
{
|
||||
struct perf_session *session;
|
||||
@ -1639,7 +1643,7 @@ int cmd_report(int argc, const char **argv)
|
||||
symbol_conf.use_callchain = true;
|
||||
callchain_register_param(&callchain_param);
|
||||
if (sort_order == NULL)
|
||||
sort_order = "srcline,symbol,dso";
|
||||
sort_order = CALLCHAIN_BRANCH_SORT_ORDER;
|
||||
}
|
||||
|
||||
if (report.mem_mode) {
|
||||
|
@ -218,6 +218,9 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||
hists__new_col_len(hists, HISTC_LOCAL_P_STAGE_CYC, 13);
|
||||
hists__new_col_len(hists, HISTC_GLOBAL_P_STAGE_CYC, 13);
|
||||
hists__new_col_len(hists, HISTC_ADDR, BITS_PER_LONG / 4 + 2);
|
||||
hists__new_col_len(hists, HISTC_CALLCHAIN_BRANCH_PREDICTED, 9);
|
||||
hists__new_col_len(hists, HISTC_CALLCHAIN_BRANCH_ABORT, 5);
|
||||
hists__new_col_len(hists, HISTC_CALLCHAIN_BRANCH_CYCLES, 6);
|
||||
|
||||
if (symbol_conf.nanosecs)
|
||||
hists__new_col_len(hists, HISTC_TIME, 16);
|
||||
|
@ -87,6 +87,9 @@ enum hist_column {
|
||||
HISTC_TYPE_OFFSET,
|
||||
HISTC_SYMBOL_OFFSET,
|
||||
HISTC_TYPE_CACHELINE,
|
||||
HISTC_CALLCHAIN_BRANCH_PREDICTED,
|
||||
HISTC_CALLCHAIN_BRANCH_ABORT,
|
||||
HISTC_CALLCHAIN_BRANCH_CYCLES,
|
||||
HISTC_NR_COLS, /* Last entry */
|
||||
};
|
||||
|
||||
|
@ -677,6 +677,102 @@ struct sort_entry sort_sym_ipc_null = {
|
||||
.se_width_idx = HISTC_SYMBOL_IPC,
|
||||
};
|
||||
|
||||
/* --sort callchain_branch_predicted */
|
||||
|
||||
static int64_t
|
||||
sort__callchain_branch_predicted_cmp(struct hist_entry *left __maybe_unused,
|
||||
struct hist_entry *right __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hist_entry__callchain_branch_predicted_snprintf(
|
||||
struct hist_entry *he, char *bf, size_t size, unsigned int width)
|
||||
{
|
||||
u64 branch_count, predicted_count;
|
||||
double percent = 0.0;
|
||||
char str[32];
|
||||
|
||||
callchain_branch_counts(he->callchain, &branch_count,
|
||||
&predicted_count, NULL, NULL);
|
||||
|
||||
if (branch_count)
|
||||
percent = predicted_count * 100.0 / branch_count;
|
||||
|
||||
snprintf(str, sizeof(str), "%.1f%%", percent);
|
||||
return repsep_snprintf(bf, size, "%-*.*s", width, width, str);
|
||||
}
|
||||
|
||||
struct sort_entry sort_callchain_branch_predicted = {
|
||||
.se_header = "Predicted",
|
||||
.se_cmp = sort__callchain_branch_predicted_cmp,
|
||||
.se_snprintf = hist_entry__callchain_branch_predicted_snprintf,
|
||||
.se_width_idx = HISTC_CALLCHAIN_BRANCH_PREDICTED,
|
||||
};
|
||||
|
||||
/* --sort callchain_branch_abort */
|
||||
|
||||
static int64_t
|
||||
sort__callchain_branch_abort_cmp(struct hist_entry *left __maybe_unused,
|
||||
struct hist_entry *right __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hist_entry__callchain_branch_abort_snprintf(struct hist_entry *he,
|
||||
char *bf, size_t size,
|
||||
unsigned int width)
|
||||
{
|
||||
u64 branch_count, abort_count;
|
||||
char str[32];
|
||||
|
||||
callchain_branch_counts(he->callchain, &branch_count,
|
||||
NULL, &abort_count, NULL);
|
||||
|
||||
snprintf(str, sizeof(str), "%" PRId64, abort_count);
|
||||
return repsep_snprintf(bf, size, "%-*.*s", width, width, str);
|
||||
}
|
||||
|
||||
struct sort_entry sort_callchain_branch_abort = {
|
||||
.se_header = "Abort",
|
||||
.se_cmp = sort__callchain_branch_abort_cmp,
|
||||
.se_snprintf = hist_entry__callchain_branch_abort_snprintf,
|
||||
.se_width_idx = HISTC_CALLCHAIN_BRANCH_ABORT,
|
||||
};
|
||||
|
||||
/* --sort callchain_branch_cycles */
|
||||
|
||||
static int64_t
|
||||
sort__callchain_branch_cycles_cmp(struct hist_entry *left __maybe_unused,
|
||||
struct hist_entry *right __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hist_entry__callchain_branch_cycles_snprintf(struct hist_entry *he,
|
||||
char *bf, size_t size,
|
||||
unsigned int width)
|
||||
{
|
||||
u64 branch_count, cycles_count, cycles = 0;
|
||||
char str[32];
|
||||
|
||||
callchain_branch_counts(he->callchain, &branch_count,
|
||||
NULL, NULL, &cycles_count);
|
||||
|
||||
if (branch_count)
|
||||
cycles = cycles_count / branch_count;
|
||||
|
||||
snprintf(str, sizeof(str), "%" PRId64 "", cycles);
|
||||
return repsep_snprintf(bf, size, "%-*.*s", width, width, str);
|
||||
}
|
||||
|
||||
struct sort_entry sort_callchain_branch_cycles = {
|
||||
.se_header = "Cycles",
|
||||
.se_cmp = sort__callchain_branch_cycles_cmp,
|
||||
.se_snprintf = hist_entry__callchain_branch_cycles_snprintf,
|
||||
.se_width_idx = HISTC_CALLCHAIN_BRANCH_CYCLES,
|
||||
};
|
||||
|
||||
/* --sort srcfile */
|
||||
|
||||
static char no_srcfile[1];
|
||||
@ -2456,6 +2552,15 @@ static struct sort_dimension bstack_sort_dimensions[] = {
|
||||
DIM(SORT_SYM_IPC, "ipc_lbr", sort_sym_ipc),
|
||||
DIM(SORT_ADDR_FROM, "addr_from", sort_addr_from),
|
||||
DIM(SORT_ADDR_TO, "addr_to", sort_addr_to),
|
||||
DIM(SORT_CALLCHAIN_BRANCH_PREDICTED,
|
||||
"callchain_branch_predicted",
|
||||
sort_callchain_branch_predicted),
|
||||
DIM(SORT_CALLCHAIN_BRANCH_ABORT,
|
||||
"callchain_branch_abort",
|
||||
sort_callchain_branch_abort),
|
||||
DIM(SORT_CALLCHAIN_BRANCH_CYCLES,
|
||||
"callchain_branch_cycles",
|
||||
sort_callchain_branch_cycles)
|
||||
};
|
||||
|
||||
#undef DIM
|
||||
@ -3484,7 +3589,13 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
|
||||
if (!sd->name || strncasecmp(tok, sd->name, strlen(tok)))
|
||||
continue;
|
||||
|
||||
if (sort__mode != SORT_MODE__BRANCH)
|
||||
if ((sort__mode != SORT_MODE__BRANCH) &&
|
||||
strncasecmp(tok, "callchain_branch_predicted",
|
||||
strlen(tok)) &&
|
||||
strncasecmp(tok, "callchain_branch_abort",
|
||||
strlen(tok)) &&
|
||||
strncasecmp(tok, "callchain_branch_cycles",
|
||||
strlen(tok)))
|
||||
return -EINVAL;
|
||||
|
||||
if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
|
||||
|
@ -88,6 +88,9 @@ enum sort_type {
|
||||
SORT_SYM_IPC,
|
||||
SORT_ADDR_FROM,
|
||||
SORT_ADDR_TO,
|
||||
SORT_CALLCHAIN_BRANCH_PREDICTED,
|
||||
SORT_CALLCHAIN_BRANCH_ABORT,
|
||||
SORT_CALLCHAIN_BRANCH_CYCLES,
|
||||
|
||||
/* memory mode specific sort keys */
|
||||
__SORT_MEMORY_MODE,
|
||||
|
Loading…
Reference in New Issue
Block a user