Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: linux-toolchains@vger.kernel.org
Cc: linux-trace-devel@vger.kernel.org
Link: https://lore.kernel.org/r/20231213001323.718046-18-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
58824fa0 61a9741e

+87
+41
tools/perf/builtin-annotate.c
··· 58 58 bool group_set; 59 59 bool data_type; 60 60 bool type_stat; 61 + bool insn_stat; 61 62 float min_percent; 62 63 const char *sym_hist_filter; 63 64 const char *cpu_list; ··· 435 434 #undef PRINT_STAT 436 435 } 437 436 437 + static void print_annotate_item_stat(struct list_head *head, const char *title) 438 + { 439 + struct annotated_item_stat *istat, *pos, *iter; 440 + int total_good, total_bad, total; 441 + int sum1, sum2; 442 + LIST_HEAD(tmp); 443 + 444 + /* sort the list by count */ 445 + list_splice_init(head, &tmp); 446 + total_good = total_bad = 0; 447 + 448 + list_for_each_entry_safe(istat, pos, &tmp, list) { 449 + total_good += istat->good; 450 + total_bad += istat->bad; 451 + sum1 = istat->good + istat->bad; 452 + 453 + list_for_each_entry(iter, head, list) { 454 + sum2 = iter->good + iter->bad; 455 + if (sum1 > sum2) 456 + break; 457 + } 458 + list_move_tail(&istat->list, &iter->list); 459 + } 460 + total = total_good + total_bad; 461 + 462 + printf("Annotate %s stats\n", title); 463 + printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n\n", total, 464 + total_good, 100.0 * total_good / (total ?: 1), 465 + total_bad, 100.0 * total_bad / (total ?: 1)); 466 + printf(" %-10s: %5s %5s\n", "Name", "Good", "Bad"); 467 + printf("-----------------------------------------------------------\n"); 468 + list_for_each_entry(istat, head, list) 469 + printf(" %-10s: %5d %5d\n", istat->name, istat->good, istat->bad); 470 + printf("\n"); 471 + } 472 + 438 473 static void hists__find_annotations(struct hists *hists, 439 474 struct evsel *evsel, 440 475 struct perf_annotate *ann) ··· 480 443 481 444 if (ann->type_stat) 482 445 print_annotate_data_stat(&ann_data_stat); 446 + if (ann->insn_stat) 447 + print_annotate_item_stat(&ann_insn_stat, "Instruction"); 483 448 484 449 while (nd) { 485 450 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); ··· 831 792 parse_data_type), 832 793 OPT_BOOLEAN(0, "type-stat", &annotate.type_stat, 833 794 "Show stats for the data type annotation"), 795 + OPT_BOOLEAN(0, "insn-stat", &annotate.insn_stat, 796 + "Show instruction stats for the data type annotation"), 834 797 OPT_END() 835 798 }; 836 799 int ret;
+38
tools/perf/util/annotate.c
··· 105 105 106 106 /* Data type collection debug statistics */ 107 107 struct annotated_data_stat ann_data_stat; 108 + LIST_HEAD(ann_insn_stat); 108 109 109 110 static int arch__grow_instructions(struct arch *arch) 110 111 { ··· 3666 3665 return NULL; 3667 3666 } 3668 3667 3668 + static struct annotated_item_stat *annotate_data_stat(struct list_head *head, 3669 + const char *name) 3670 + { 3671 + struct annotated_item_stat *istat; 3672 + 3673 + list_for_each_entry(istat, head, list) { 3674 + if (!strcmp(istat->name, name)) 3675 + return istat; 3676 + } 3677 + 3678 + istat = zalloc(sizeof(*istat)); 3679 + if (istat == NULL) 3680 + return NULL; 3681 + 3682 + istat->name = strdup(name); 3683 + if (istat->name == NULL) { 3684 + free(istat); 3685 + return NULL; 3686 + } 3687 + 3688 + list_add_tail(&istat->list, head); 3689 + return istat; 3690 + } 3691 + 3669 3692 /** 3670 3693 * hist_entry__get_data_type - find data type for given hist entry 3671 3694 * @he: hist entry ··· 3708 3683 struct annotated_insn_loc loc; 3709 3684 struct annotated_op_loc *op_loc; 3710 3685 struct annotated_data_type *mem_type; 3686 + struct annotated_item_stat *istat; 3711 3687 u64 ip = he->ip; 3712 3688 int i; 3713 3689 ··· 3742 3716 return NULL; 3743 3717 } 3744 3718 3719 + istat = annotate_data_stat(&ann_insn_stat, dl->ins.name); 3720 + if (istat == NULL) { 3721 + ann_data_stat.no_insn++; 3722 + return NULL; 3723 + } 3724 + 3745 3725 if (annotate_get_insn_location(arch, dl, &loc) < 0) { 3746 3726 ann_data_stat.no_insn_ops++; 3727 + istat->bad++; 3747 3728 return NULL; 3748 3729 } 3749 3730 ··· 3759 3726 continue; 3760 3727 3761 3728 mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset); 3729 + if (mem_type) 3730 + istat->good++; 3731 + else 3732 + istat->bad++; 3762 3733 3763 3734 if (symbol_conf.annotate_data_sample) { 3764 3735 annotated_data_type__update_samples(mem_type, evsel, ··· 3775 3738 } 3776 3739 3777 3740 ann_data_stat.no_mem_ops++; 3741 + istat->bad++; 3778 3742 return NULL; 3779 3743 }
+8
tools/perf/util/annotate.h
··· 479 479 /* Returns a data type from the sample instruction (if any) */ 480 480 struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he); 481 481 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 + 482 490 #endif /* __PERF_ANNOTATE_H */