Skip to content

Commit 58824fa

Browse files
namhyungacmel
authored andcommitted
perf annotate: Add --insn-stat option for debugging
This is for a debugging purpose. It'd be useful to see per-instrucion level success/failure stats. $ perf annotate --data-type --insn-stat Annotate Instruction stats total 264, ok 143 (54.2%), bad 121 (45.8%) Name : Good Bad ----------------------------------------------------------- movq : 45 31 movl : 22 11 popq : 0 19 cmpl : 16 3 addq : 8 7 cmpq : 11 3 cmpxchgl : 3 7 cmpxchgq : 8 0 incl : 3 3 movzbl : 4 2 incq : 4 2 decl : 6 0 ... Committer notes: So these are about being able to find the type for accesses from these instructions, we should improve the naming, but it is for debugging, we can improve this later: @@ -3726,6 +3759,10 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) continue; mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset); + if (mem_type) + istat->good++; + else + istat->bad++; Signed-off-by: Namhyung Kim <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: [email protected] Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 61a9741 commit 58824fa

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

tools/perf/builtin-annotate.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct perf_annotate {
5858
bool group_set;
5959
bool data_type;
6060
bool type_stat;
61+
bool insn_stat;
6162
float min_percent;
6263
const char *sym_hist_filter;
6364
const char *cpu_list;
@@ -434,6 +435,42 @@ static void print_annotate_data_stat(struct annotated_data_stat *s)
434435
#undef PRINT_STAT
435436
}
436437

438+
static void print_annotate_item_stat(struct list_head *head, const char *title)
439+
{
440+
struct annotated_item_stat *istat, *pos, *iter;
441+
int total_good, total_bad, total;
442+
int sum1, sum2;
443+
LIST_HEAD(tmp);
444+
445+
/* sort the list by count */
446+
list_splice_init(head, &tmp);
447+
total_good = total_bad = 0;
448+
449+
list_for_each_entry_safe(istat, pos, &tmp, list) {
450+
total_good += istat->good;
451+
total_bad += istat->bad;
452+
sum1 = istat->good + istat->bad;
453+
454+
list_for_each_entry(iter, head, list) {
455+
sum2 = iter->good + iter->bad;
456+
if (sum1 > sum2)
457+
break;
458+
}
459+
list_move_tail(&istat->list, &iter->list);
460+
}
461+
total = total_good + total_bad;
462+
463+
printf("Annotate %s stats\n", title);
464+
printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n\n", total,
465+
total_good, 100.0 * total_good / (total ?: 1),
466+
total_bad, 100.0 * total_bad / (total ?: 1));
467+
printf(" %-10s: %5s %5s\n", "Name", "Good", "Bad");
468+
printf("-----------------------------------------------------------\n");
469+
list_for_each_entry(istat, head, list)
470+
printf(" %-10s: %5d %5d\n", istat->name, istat->good, istat->bad);
471+
printf("\n");
472+
}
473+
437474
static void hists__find_annotations(struct hists *hists,
438475
struct evsel *evsel,
439476
struct perf_annotate *ann)
@@ -443,6 +480,8 @@ static void hists__find_annotations(struct hists *hists,
443480

444481
if (ann->type_stat)
445482
print_annotate_data_stat(&ann_data_stat);
483+
if (ann->insn_stat)
484+
print_annotate_item_stat(&ann_insn_stat, "Instruction");
446485

447486
while (nd) {
448487
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
@@ -792,6 +831,8 @@ int cmd_annotate(int argc, const char **argv)
792831
parse_data_type),
793832
OPT_BOOLEAN(0, "type-stat", &annotate.type_stat,
794833
"Show stats for the data type annotation"),
834+
OPT_BOOLEAN(0, "insn-stat", &annotate.insn_stat,
835+
"Show instruction stats for the data type annotation"),
795836
OPT_END()
796837
};
797838
int ret;

tools/perf/util/annotate.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static struct ins_ops ret_ops;
105105

106106
/* Data type collection debug statistics */
107107
struct annotated_data_stat ann_data_stat;
108+
LIST_HEAD(ann_insn_stat);
108109

109110
static int arch__grow_instructions(struct arch *arch)
110111
{
@@ -3665,6 +3666,30 @@ static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip)
36653666
return NULL;
36663667
}
36673668

3669+
static struct annotated_item_stat *annotate_data_stat(struct list_head *head,
3670+
const char *name)
3671+
{
3672+
struct annotated_item_stat *istat;
3673+
3674+
list_for_each_entry(istat, head, list) {
3675+
if (!strcmp(istat->name, name))
3676+
return istat;
3677+
}
3678+
3679+
istat = zalloc(sizeof(*istat));
3680+
if (istat == NULL)
3681+
return NULL;
3682+
3683+
istat->name = strdup(name);
3684+
if (istat->name == NULL) {
3685+
free(istat);
3686+
return NULL;
3687+
}
3688+
3689+
list_add_tail(&istat->list, head);
3690+
return istat;
3691+
}
3692+
36683693
/**
36693694
* hist_entry__get_data_type - find data type for given hist entry
36703695
* @he: hist entry
@@ -3683,6 +3708,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he)
36833708
struct annotated_insn_loc loc;
36843709
struct annotated_op_loc *op_loc;
36853710
struct annotated_data_type *mem_type;
3711+
struct annotated_item_stat *istat;
36863712
u64 ip = he->ip;
36873713
int i;
36883714

@@ -3716,8 +3742,15 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he)
37163742
return NULL;
37173743
}
37183744

3745+
istat = annotate_data_stat(&ann_insn_stat, dl->ins.name);
3746+
if (istat == NULL) {
3747+
ann_data_stat.no_insn++;
3748+
return NULL;
3749+
}
3750+
37193751
if (annotate_get_insn_location(arch, dl, &loc) < 0) {
37203752
ann_data_stat.no_insn_ops++;
3753+
istat->bad++;
37213754
return NULL;
37223755
}
37233756

@@ -3726,6 +3759,10 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he)
37263759
continue;
37273760

37283761
mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset);
3762+
if (mem_type)
3763+
istat->good++;
3764+
else
3765+
istat->bad++;
37293766

37303767
if (symbol_conf.annotate_data_sample) {
37313768
annotated_data_type__update_samples(mem_type, evsel,
@@ -3738,5 +3775,6 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he)
37383775
}
37393776

37403777
ann_data_stat.no_mem_ops++;
3778+
istat->bad++;
37413779
return NULL;
37423780
}

tools/perf/util/annotate.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,4 +479,12 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl,
479479
/* Returns a data type from the sample instruction (if any) */
480480
struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he);
481481

482+
struct annotated_item_stat {
483+
struct list_head list;
484+
char *name;
485+
int good;
486+
int bad;
487+
};
488+
extern struct list_head ann_insn_stat;
489+
482490
#endif /* __PERF_ANNOTATE_H */

0 commit comments

Comments
 (0)