perf report: Display the branch counter histogram
Reusing the existing --total-cycles option to display the branch counters. Add a new PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER to display the logged branch counter events. They are shown right after all the cycle-related annotations. Extend the 'struct block_info' to store and pass the branch counter related information. The annotation_br_cntr_entry() is to print the histogram of each branch counter event. If the number of logged events is less than 4, the exact number of the abbr name is printed. Otherwise, using '+' to stands for more than 3 events. Assume the number of logged events is less than 4. The annotation_br_cntr_abbr_list() prints the branch counter's abbreviation list. Press 'B' to display the list in the TUI mode. $ perf record -e "{branch-instructions:ppp,branch-misses}:S" -j any,counter $ perf report --total-cycles --stdio # To display the perf.data header info, please use --header/--header-only options. # # # Total Lost Samples: 0 # # Samples: 1M of events 'anon group { branch-instructions:ppp, branch-misses }' # Event count (approx.): 1610046 # # Branch counter abbr list: # branch-instructions:ppp = A # branch-misses = B # '-' No event occurs # '+' Event occurrences may be lost due to branch counter saturated # # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch Counter [Program Block Range] # ............... .............. ........... .......... .............. .................. # 57.55% 2.5M 0.00% 3 |A |- | ... 25.27% 1.1M 0.00% 2 |AA |- | ... 15.61% 667.2K 0.00% 1 |A |- | ... 0.16% 6.9K 0.81% 575 |A |- | ... 0.16% 6.8K 1.38% 977 |AA |- | ... 0.16% 6.8K 0.04% 28 |AA |B | ... 0.15% 6.6K 1.33% 946 |A |- | ... 0.11% 4.5K 0.06% 46 |AAA+|- | ... 0.10% 4.4K 0.88% 624 |A |- | ... 0.09% 3.7K 0.74% 524 |AAA+|B | ... With -v applied, # Sampled Cycles% Sampled Cycles Avg Cycles% Avg Cycles Branch Counter [Program Block Range] # ............... .............. ........... .......... .............. .................. # 57.55% 2.5M 0.00% 3 A=1 ,B=- ... 25.27% 1.1M 0.00% 2 A=2 ,B=- ... 15.61% 667.2K 0.00% 1 A=1 ,B=- ... 0.16% 6.9K 0.81% 575 A=1 ,B=- ... 0.16% 6.8K 1.38% 977 A=2 ,B=- ... 0.16% 6.8K 0.04% 28 A=2 ,B=1 ... 0.15% 6.6K 1.33% 946 A=1 ,B=- ... 0.11% 4.5K 0.06% 46 A=3+,B=- ... 0.10% 4.4K 0.88% 624 A=1 ,B=- ... 0.09% 3.7K 0.74% 524 A=3+,B=1 ... Reviewed-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Kan Liang <kan.liang@linux.intel.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Ian Rogers <irogers@google.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: https://lore.kernel.org/r/20240813160208.2493643-7-kan.liang@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
7398bf181d
commit
20d6f55528
@ -614,6 +614,7 @@ include::itrace.txt[]
|
||||
'Avg Cycles%' - block average sampled cycles / sum of total block average
|
||||
sampled cycles
|
||||
'Avg Cycles' - block average sampled cycles
|
||||
'Branch Counter' - block branch counter histogram (with -v showing the number)
|
||||
|
||||
--skip-empty::
|
||||
Do not print 0 results in the --stat output.
|
||||
|
@ -691,7 +691,7 @@ static void hists__precompute(struct hists *hists)
|
||||
if (compute == COMPUTE_CYCLES) {
|
||||
bh = container_of(he, struct block_hist, he);
|
||||
init_block_hist(bh);
|
||||
block_info__process_sym(he, bh, NULL, 0);
|
||||
block_info__process_sym(he, bh, NULL, 0, 0);
|
||||
}
|
||||
|
||||
data__for_each_file_new(i, d) {
|
||||
@ -714,7 +714,7 @@ static void hists__precompute(struct hists *hists)
|
||||
pair_bh = container_of(pair, struct block_hist,
|
||||
he);
|
||||
init_block_hist(pair_bh);
|
||||
block_info__process_sym(pair, pair_bh, NULL, 0);
|
||||
block_info__process_sym(pair, pair_bh, NULL, 0, 0);
|
||||
|
||||
bh = container_of(he, struct block_hist, he);
|
||||
|
||||
|
@ -575,6 +575,13 @@ static int evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, c
|
||||
hists__fprintf_nr_sample_events(hists, rep, evname, stdout);
|
||||
|
||||
if (rep->total_cycles_mode) {
|
||||
char *buf;
|
||||
|
||||
if (!annotation_br_cntr_abbr_list(&buf, pos, true)) {
|
||||
fprintf(stdout, "%s", buf);
|
||||
fprintf(stdout, "#\n");
|
||||
free(buf);
|
||||
}
|
||||
report__browse_block_hists(&rep->block_reports[i - 1].hist,
|
||||
rep->min_percent, pos, NULL);
|
||||
continue;
|
||||
@ -1119,18 +1126,23 @@ static int __cmd_report(struct report *rep)
|
||||
report__output_resort(rep);
|
||||
|
||||
if (rep->total_cycles_mode) {
|
||||
int block_hpps[6] = {
|
||||
int nr_hpps = 4;
|
||||
int block_hpps[PERF_HPP_REPORT__BLOCK_MAX_INDEX] = {
|
||||
PERF_HPP_REPORT__BLOCK_TOTAL_CYCLES_PCT,
|
||||
PERF_HPP_REPORT__BLOCK_LBR_CYCLES,
|
||||
PERF_HPP_REPORT__BLOCK_CYCLES_PCT,
|
||||
PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
|
||||
PERF_HPP_REPORT__BLOCK_RANGE,
|
||||
PERF_HPP_REPORT__BLOCK_DSO,
|
||||
};
|
||||
|
||||
if (session->evlist->nr_br_cntr > 0)
|
||||
block_hpps[nr_hpps++] = PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER;
|
||||
|
||||
block_hpps[nr_hpps++] = PERF_HPP_REPORT__BLOCK_RANGE;
|
||||
block_hpps[nr_hpps++] = PERF_HPP_REPORT__BLOCK_DSO;
|
||||
|
||||
rep->block_reports = block_info__create_report(session->evlist,
|
||||
rep->total_cycles,
|
||||
block_hpps, 6,
|
||||
block_hpps, nr_hpps,
|
||||
&rep->nr_block_reports);
|
||||
if (!rep->block_reports)
|
||||
return -1;
|
||||
|
@ -3684,8 +3684,10 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
|
||||
struct hist_browser *browser;
|
||||
int key = -1;
|
||||
struct popup_action action;
|
||||
char *br_cntr_text = NULL;
|
||||
static const char help[] =
|
||||
" q Quit \n";
|
||||
" q Quit \n"
|
||||
" B Branch counter abbr list (Optional)\n";
|
||||
|
||||
browser = hist_browser__new(hists);
|
||||
if (!browser)
|
||||
@ -3703,6 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
|
||||
|
||||
memset(&action, 0, sizeof(action));
|
||||
|
||||
annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false);
|
||||
|
||||
while (1) {
|
||||
key = hist_browser__run(browser, "? - help", true, 0);
|
||||
|
||||
@ -3723,6 +3727,16 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
|
||||
action.ms.sym = browser->selection->sym;
|
||||
do_annotate(browser, &action);
|
||||
continue;
|
||||
case 'B':
|
||||
if (br_cntr_text) {
|
||||
ui__question_window("Branch counter abbr list",
|
||||
br_cntr_text, "Press any key...", 0);
|
||||
} else {
|
||||
ui__question_window("Branch counter abbr list",
|
||||
"\n The branch counter is not available.\n",
|
||||
"Press any key...", 0);
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -3730,5 +3744,6 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
|
||||
|
||||
out:
|
||||
hist_browser__delete(browser);
|
||||
free(br_cntr_text);
|
||||
return 0;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "namespaces.h"
|
||||
#include "thread.h"
|
||||
#include "hashmap.h"
|
||||
#include "strbuf.h"
|
||||
#include <regex.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -48,6 +49,7 @@
|
||||
#include <linux/zalloc.h>
|
||||
#include <subcmd/parse-options.h>
|
||||
#include <subcmd/run-command.h>
|
||||
#include <math.h>
|
||||
|
||||
/* FIXME: For the HE_COLORSET */
|
||||
#include "ui/browser.h"
|
||||
@ -1719,6 +1721,149 @@ static void ipc_coverage_string(char *bf, int size, struct annotation *notes)
|
||||
ipc, coverage);
|
||||
}
|
||||
|
||||
int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool header)
|
||||
{
|
||||
struct evsel *pos;
|
||||
struct strbuf sb;
|
||||
|
||||
if (evsel->evlist->nr_br_cntr <= 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
strbuf_init(&sb, /*hint=*/ 0);
|
||||
|
||||
if (header && strbuf_addf(&sb, "# Branch counter abbr list:\n"))
|
||||
goto err;
|
||||
|
||||
evlist__for_each_entry(evsel->evlist, pos) {
|
||||
if (!(pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS))
|
||||
continue;
|
||||
if (header && strbuf_addf(&sb, "#"))
|
||||
goto err;
|
||||
|
||||
if (strbuf_addf(&sb, " %s = %s\n", pos->name, pos->abbr_name))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (header && strbuf_addf(&sb, "#"))
|
||||
goto err;
|
||||
if (strbuf_addf(&sb, " '-' No event occurs\n"))
|
||||
goto err;
|
||||
|
||||
if (header && strbuf_addf(&sb, "#"))
|
||||
goto err;
|
||||
if (strbuf_addf(&sb, " '+' Event occurrences may be lost due to branch counter saturated\n"))
|
||||
goto err;
|
||||
|
||||
*str = strbuf_detach(&sb, NULL);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
strbuf_release(&sb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Assume the branch counter saturated at 3 */
|
||||
#define ANNOTATION_BR_CNTR_SATURATION 3
|
||||
|
||||
int annotation_br_cntr_entry(char **str, int br_cntr_nr,
|
||||
u64 *br_cntr, int num_aggr,
|
||||
struct evsel *evsel)
|
||||
{
|
||||
struct evsel *pos = evsel ? evlist__first(evsel->evlist) : NULL;
|
||||
bool saturated = false;
|
||||
int i, j, avg, used;
|
||||
struct strbuf sb;
|
||||
|
||||
strbuf_init(&sb, /*hint=*/ 0);
|
||||
for (i = 0; i < br_cntr_nr; i++) {
|
||||
used = 0;
|
||||
avg = ceil((double)(br_cntr[i] & ~ANNOTATION__BR_CNTR_SATURATED_FLAG) /
|
||||
(double)num_aggr);
|
||||
|
||||
/*
|
||||
* A histogram with the abbr name is displayed by default.
|
||||
* With -v, the exact number of branch counter is displayed.
|
||||
*/
|
||||
if (verbose) {
|
||||
evlist__for_each_entry_from(evsel->evlist, pos) {
|
||||
if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) &&
|
||||
(pos->br_cntr_idx == i))
|
||||
break;
|
||||
}
|
||||
if (strbuf_addstr(&sb, pos->abbr_name))
|
||||
goto err;
|
||||
|
||||
if (!br_cntr[i]) {
|
||||
if (strbuf_addstr(&sb, "=-"))
|
||||
goto err;
|
||||
} else {
|
||||
if (strbuf_addf(&sb, "=%d", avg))
|
||||
goto err;
|
||||
}
|
||||
if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG) {
|
||||
if (strbuf_addch(&sb, '+'))
|
||||
goto err;
|
||||
} else {
|
||||
if (strbuf_addch(&sb, ' '))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((i < br_cntr_nr - 1) && strbuf_addch(&sb, ','))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strbuf_addch(&sb, '|'))
|
||||
goto err;
|
||||
|
||||
if (!br_cntr[i]) {
|
||||
if (strbuf_addch(&sb, '-'))
|
||||
goto err;
|
||||
used++;
|
||||
} else {
|
||||
evlist__for_each_entry_from(evsel->evlist, pos) {
|
||||
if ((pos->core.attr.branch_sample_type & PERF_SAMPLE_BRANCH_COUNTERS) &&
|
||||
(pos->br_cntr_idx == i))
|
||||
break;
|
||||
}
|
||||
if (br_cntr[i] & ANNOTATION__BR_CNTR_SATURATED_FLAG)
|
||||
saturated = true;
|
||||
|
||||
for (j = 0; j < avg; j++, used++) {
|
||||
/* Print + if the number of logged events > 3 */
|
||||
if (j >= ANNOTATION_BR_CNTR_SATURATION) {
|
||||
saturated = true;
|
||||
break;
|
||||
}
|
||||
if (strbuf_addstr(&sb, pos->abbr_name))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (saturated) {
|
||||
if (strbuf_addch(&sb, '+'))
|
||||
goto err;
|
||||
used++;
|
||||
}
|
||||
pos = list_next_entry(pos, core.node);
|
||||
}
|
||||
|
||||
for (j = used; j < ANNOTATION_BR_CNTR_SATURATION + 1; j++) {
|
||||
if (strbuf_addch(&sb, ' '))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!verbose && strbuf_addch(&sb, br_cntr_nr ? '|' : ' '))
|
||||
goto err;
|
||||
|
||||
*str = strbuf_detach(&sb, NULL);
|
||||
|
||||
return 0;
|
||||
err:
|
||||
strbuf_release(&sb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void __annotation_line__write(struct annotation_line *al, struct annotation *notes,
|
||||
bool first_line, bool current_entry, bool change_color, int width,
|
||||
void *obj, unsigned int percent_type,
|
||||
|
@ -553,4 +553,7 @@ int annotate_get_basic_blocks(struct symbol *sym, s64 src, s64 dst,
|
||||
|
||||
void debuginfo_cache__delete(void);
|
||||
|
||||
int annotation_br_cntr_entry(char **str, int br_cntr_nr, u64 *br_cntr,
|
||||
int num_aggr, struct evsel *evsel);
|
||||
int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool header);
|
||||
#endif /* __PERF_ANNOTATE_H */
|
||||
|
@ -40,16 +40,32 @@ static struct block_header_column {
|
||||
[PERF_HPP_REPORT__BLOCK_DSO] = {
|
||||
.name = "Shared Object",
|
||||
.width = 20,
|
||||
},
|
||||
[PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER] = {
|
||||
.name = "Branch Counter",
|
||||
.width = 30,
|
||||
}
|
||||
};
|
||||
|
||||
struct block_info *block_info__new(void)
|
||||
static struct block_info *block_info__new(unsigned int br_cntr_nr)
|
||||
{
|
||||
return zalloc(sizeof(struct block_info));
|
||||
struct block_info *bi = zalloc(sizeof(struct block_info));
|
||||
|
||||
if (bi && br_cntr_nr) {
|
||||
bi->br_cntr = calloc(br_cntr_nr, sizeof(u64));
|
||||
if (!bi->br_cntr) {
|
||||
free(bi);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return bi;
|
||||
}
|
||||
|
||||
void block_info__delete(struct block_info *bi)
|
||||
{
|
||||
if (bi)
|
||||
free(bi->br_cntr);
|
||||
free(bi);
|
||||
}
|
||||
|
||||
@ -86,7 +102,8 @@ int64_t block_info__cmp(struct perf_hpp_fmt *fmt __maybe_unused,
|
||||
|
||||
static void init_block_info(struct block_info *bi, struct symbol *sym,
|
||||
struct cyc_hist *ch, int offset,
|
||||
u64 total_cycles)
|
||||
u64 total_cycles, unsigned int br_cntr_nr,
|
||||
u64 *br_cntr, struct evsel *evsel)
|
||||
{
|
||||
bi->sym = sym;
|
||||
bi->start = ch->start;
|
||||
@ -99,10 +116,18 @@ static void init_block_info(struct block_info *bi, struct symbol *sym,
|
||||
|
||||
memcpy(bi->cycles_spark, ch->cycles_spark,
|
||||
NUM_SPARKS * sizeof(u64));
|
||||
|
||||
if (br_cntr && br_cntr_nr) {
|
||||
bi->br_cntr_nr = br_cntr_nr;
|
||||
memcpy(bi->br_cntr, &br_cntr[offset * br_cntr_nr],
|
||||
br_cntr_nr * sizeof(u64));
|
||||
}
|
||||
bi->evsel = evsel;
|
||||
}
|
||||
|
||||
int block_info__process_sym(struct hist_entry *he, struct block_hist *bh,
|
||||
u64 *block_cycles_aggr, u64 total_cycles)
|
||||
u64 *block_cycles_aggr, u64 total_cycles,
|
||||
unsigned int br_cntr_nr)
|
||||
{
|
||||
struct annotation *notes;
|
||||
struct cyc_hist *ch;
|
||||
@ -125,12 +150,14 @@ int block_info__process_sym(struct hist_entry *he, struct block_hist *bh,
|
||||
struct block_info *bi;
|
||||
struct hist_entry *he_block;
|
||||
|
||||
bi = block_info__new();
|
||||
bi = block_info__new(br_cntr_nr);
|
||||
if (!bi)
|
||||
return -1;
|
||||
|
||||
init_block_info(bi, he->ms.sym, &ch[i], i,
|
||||
total_cycles);
|
||||
total_cycles, br_cntr_nr,
|
||||
notes->branch->br_cntr,
|
||||
hists_to_evsel(he->hists));
|
||||
cycles += bi->cycles_aggr / bi->num_aggr;
|
||||
|
||||
he_block = hists__add_entry_block(&bh->block_hists,
|
||||
@ -327,6 +354,24 @@ static void init_block_header(struct block_fmt *block_fmt)
|
||||
fmt->width = block_column_width;
|
||||
}
|
||||
|
||||
static int block_branch_counter_entry(struct perf_hpp_fmt *fmt,
|
||||
struct perf_hpp *hpp,
|
||||
struct hist_entry *he)
|
||||
{
|
||||
struct block_fmt *block_fmt = container_of(fmt, struct block_fmt, fmt);
|
||||
struct block_info *bi = he->block_info;
|
||||
char *buf;
|
||||
int ret;
|
||||
|
||||
if (annotation_br_cntr_entry(&buf, bi->br_cntr_nr, bi->br_cntr,
|
||||
bi->num_aggr, bi->evsel))
|
||||
return 0;
|
||||
|
||||
ret = scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, buf);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hpp_register(struct block_fmt *block_fmt, int idx,
|
||||
struct perf_hpp_list *hpp_list)
|
||||
{
|
||||
@ -357,6 +402,9 @@ static void hpp_register(struct block_fmt *block_fmt, int idx,
|
||||
case PERF_HPP_REPORT__BLOCK_DSO:
|
||||
fmt->entry = block_dso_entry;
|
||||
break;
|
||||
case PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER:
|
||||
fmt->entry = block_branch_counter_entry;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -390,7 +438,7 @@ static void init_block_hist(struct block_hist *bh, struct block_fmt *block_fmts,
|
||||
static int process_block_report(struct hists *hists,
|
||||
struct block_report *block_report,
|
||||
u64 total_cycles, int *block_hpps,
|
||||
int nr_hpps)
|
||||
int nr_hpps, unsigned int br_cntr_nr)
|
||||
{
|
||||
struct rb_node *next = rb_first_cached(&hists->entries);
|
||||
struct block_hist *bh = &block_report->hist;
|
||||
@ -405,7 +453,7 @@ static int process_block_report(struct hists *hists,
|
||||
while (next) {
|
||||
he = rb_entry(next, struct hist_entry, rb_node);
|
||||
block_info__process_sym(he, bh, &block_report->cycles,
|
||||
total_cycles);
|
||||
total_cycles, br_cntr_nr);
|
||||
next = rb_next(&he->rb_node);
|
||||
}
|
||||
|
||||
@ -435,7 +483,7 @@ struct block_report *block_info__create_report(struct evlist *evlist,
|
||||
struct hists *hists = evsel__hists(pos);
|
||||
|
||||
process_block_report(hists, &block_reports[i], total_cycles,
|
||||
block_hpps, nr_hpps);
|
||||
block_hpps, nr_hpps, evlist->nr_br_cntr);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,9 @@ struct block_info {
|
||||
u64 total_cycles;
|
||||
int num;
|
||||
int num_aggr;
|
||||
int br_cntr_nr;
|
||||
u64 *br_cntr;
|
||||
struct evsel *evsel;
|
||||
};
|
||||
|
||||
struct block_fmt {
|
||||
@ -36,6 +39,7 @@ enum {
|
||||
PERF_HPP_REPORT__BLOCK_AVG_CYCLES,
|
||||
PERF_HPP_REPORT__BLOCK_RANGE,
|
||||
PERF_HPP_REPORT__BLOCK_DSO,
|
||||
PERF_HPP_REPORT__BLOCK_BRANCH_COUNTER,
|
||||
PERF_HPP_REPORT__BLOCK_MAX_INDEX
|
||||
};
|
||||
|
||||
@ -46,7 +50,6 @@ struct block_report {
|
||||
int nr_fmts;
|
||||
};
|
||||
|
||||
struct block_info *block_info__new(void);
|
||||
void block_info__delete(struct block_info *bi);
|
||||
|
||||
int64_t __block_info__cmp(struct hist_entry *left, struct hist_entry *right);
|
||||
@ -55,7 +58,8 @@ int64_t block_info__cmp(struct perf_hpp_fmt *fmt __maybe_unused,
|
||||
struct hist_entry *left, struct hist_entry *right);
|
||||
|
||||
int block_info__process_sym(struct hist_entry *he, struct block_hist *bh,
|
||||
u64 *block_cycles_aggr, u64 total_cycles);
|
||||
u64 *block_cycles_aggr, u64 total_cycles,
|
||||
unsigned int br_cntr_nr);
|
||||
|
||||
struct block_report *block_info__create_report(struct evlist *evlist,
|
||||
u64 total_cycles,
|
||||
|
Loading…
Reference in New Issue
Block a user