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

Configure Feed

Select the types of activity you want to include in your feed.

perf annotate: Factor out __hist_entry__get_data_type()

So that it can only handle a single disasm_linme and hopefully make the
code simpler. This is also a preparation to be called from different
places later.

The NO_TYPE macro was added to distinguish when it failed or needs retry.

Reviewed-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250310224925.799005-6-namhyung@kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

+95 -75
+95 -75
tools/perf/util/annotate.c
··· 87 87 }, 88 88 }; 89 89 90 + #define NO_TYPE ((struct annotated_data_type *)-1UL) 91 + 90 92 /* symbol histogram: key = offset << 16 | evsel->core.idx */ 91 93 static size_t sym_hist_hash(long key, void *ctx __maybe_unused) 92 94 { ··· 2651 2649 di_cache.dbg = NULL; 2652 2650 } 2653 2651 2652 + static struct annotated_data_type * 2653 + __hist_entry__get_data_type(struct hist_entry *he, struct arch *arch, 2654 + struct debuginfo *dbg, struct disasm_line *dl, 2655 + int *type_offset) 2656 + { 2657 + struct map_symbol *ms = &he->ms; 2658 + struct annotated_insn_loc loc; 2659 + struct annotated_op_loc *op_loc; 2660 + struct annotated_data_type *mem_type; 2661 + struct annotated_item_stat *istat; 2662 + int i; 2663 + 2664 + istat = annotate_data_stat(&ann_insn_stat, dl->ins.name); 2665 + if (istat == NULL) { 2666 + ann_data_stat.no_insn++; 2667 + return NO_TYPE; 2668 + } 2669 + 2670 + if (annotate_get_insn_location(arch, dl, &loc) < 0) { 2671 + ann_data_stat.no_insn_ops++; 2672 + istat->bad++; 2673 + return NO_TYPE; 2674 + } 2675 + 2676 + if (is_stack_operation(arch, dl)) { 2677 + istat->good++; 2678 + *type_offset = 0; 2679 + return &stackop_type; 2680 + } 2681 + 2682 + for_each_insn_op_loc(&loc, i, op_loc) { 2683 + struct data_loc_info dloc = { 2684 + .arch = arch, 2685 + .thread = he->thread, 2686 + .ms = ms, 2687 + .ip = ms->sym->start + dl->al.offset, 2688 + .cpumode = he->cpumode, 2689 + .op = op_loc, 2690 + .di = dbg, 2691 + }; 2692 + 2693 + if (!op_loc->mem_ref && op_loc->segment == INSN_SEG_NONE) 2694 + continue; 2695 + 2696 + /* PC-relative addressing */ 2697 + if (op_loc->reg1 == DWARF_REG_PC) { 2698 + dloc.var_addr = annotate_calc_pcrel(ms, dloc.ip, 2699 + op_loc->offset, dl); 2700 + } 2701 + 2702 + /* This CPU access in kernel - pretend PC-relative addressing */ 2703 + if (dso__kernel(map__dso(ms->map)) && arch__is(arch, "x86") && 2704 + op_loc->segment == INSN_SEG_X86_GS && op_loc->imm) { 2705 + dloc.var_addr = op_loc->offset; 2706 + op_loc->reg1 = DWARF_REG_PC; 2707 + } 2708 + 2709 + mem_type = find_data_type(&dloc); 2710 + 2711 + if (mem_type == NULL && is_stack_canary(arch, op_loc)) { 2712 + istat->good++; 2713 + *type_offset = 0; 2714 + return &canary_type; 2715 + } 2716 + 2717 + if (mem_type) 2718 + istat->good++; 2719 + else 2720 + istat->bad++; 2721 + 2722 + if (symbol_conf.annotate_data_sample) { 2723 + struct evsel *evsel = hists_to_evsel(he->hists); 2724 + 2725 + annotated_data_type__update_samples(mem_type, evsel, 2726 + dloc.type_offset, 2727 + he->stat.nr_events, 2728 + he->stat.period); 2729 + } 2730 + *type_offset = dloc.type_offset; 2731 + return mem_type ?: NO_TYPE; 2732 + } 2733 + 2734 + /* retry with a fused instruction */ 2735 + return NULL; 2736 + } 2737 + 2654 2738 /** 2655 2739 * hist_entry__get_data_type - find data type for given hist entry 2656 2740 * @he: hist entry ··· 2752 2664 struct evsel *evsel = hists_to_evsel(he->hists); 2753 2665 struct arch *arch; 2754 2666 struct disasm_line *dl; 2755 - struct annotated_insn_loc loc; 2756 - struct annotated_op_loc *op_loc; 2757 2667 struct annotated_data_type *mem_type; 2758 2668 struct annotated_item_stat *istat; 2759 2669 u64 ip = he->ip; 2760 - int i; 2761 2670 2762 2671 ann_data_stat.total++; 2763 2672 ··· 2806 2721 } 2807 2722 2808 2723 retry: 2809 - istat = annotate_data_stat(&ann_insn_stat, dl->ins.name); 2810 - if (istat == NULL) { 2811 - ann_data_stat.no_insn++; 2812 - return NULL; 2813 - } 2814 - 2815 - if (annotate_get_insn_location(arch, dl, &loc) < 0) { 2816 - ann_data_stat.no_insn_ops++; 2817 - istat->bad++; 2818 - return NULL; 2819 - } 2820 - 2821 - if (is_stack_operation(arch, dl)) { 2822 - istat->good++; 2823 - he->mem_type_off = 0; 2824 - return &stackop_type; 2825 - } 2826 - 2827 - for_each_insn_op_loc(&loc, i, op_loc) { 2828 - struct data_loc_info dloc = { 2829 - .arch = arch, 2830 - .thread = he->thread, 2831 - .ms = ms, 2832 - /* Recalculate IP for LOCK prefix or insn fusion */ 2833 - .ip = ms->sym->start + dl->al.offset, 2834 - .cpumode = he->cpumode, 2835 - .op = op_loc, 2836 - .di = di_cache.dbg, 2837 - }; 2838 - 2839 - if (!op_loc->mem_ref && op_loc->segment == INSN_SEG_NONE) 2840 - continue; 2841 - 2842 - /* Recalculate IP because of LOCK prefix or insn fusion */ 2843 - ip = ms->sym->start + dl->al.offset; 2844 - 2845 - /* PC-relative addressing */ 2846 - if (op_loc->reg1 == DWARF_REG_PC) { 2847 - dloc.var_addr = annotate_calc_pcrel(ms, dloc.ip, 2848 - op_loc->offset, dl); 2849 - } 2850 - 2851 - /* This CPU access in kernel - pretend PC-relative addressing */ 2852 - if (dso__kernel(map__dso(ms->map)) && arch__is(arch, "x86") && 2853 - op_loc->segment == INSN_SEG_X86_GS && op_loc->imm) { 2854 - dloc.var_addr = op_loc->offset; 2855 - op_loc->reg1 = DWARF_REG_PC; 2856 - } 2857 - 2858 - mem_type = find_data_type(&dloc); 2859 - 2860 - if (mem_type == NULL && is_stack_canary(arch, op_loc)) { 2861 - istat->good++; 2862 - he->mem_type_off = 0; 2863 - return &canary_type; 2864 - } 2865 - 2866 - if (mem_type) 2867 - istat->good++; 2868 - else 2869 - istat->bad++; 2870 - 2871 - if (symbol_conf.annotate_data_sample) { 2872 - annotated_data_type__update_samples(mem_type, evsel, 2873 - dloc.type_offset, 2874 - he->stat.nr_events, 2875 - he->stat.period); 2876 - } 2877 - he->mem_type_off = dloc.type_offset; 2878 - return mem_type; 2879 - } 2724 + mem_type = __hist_entry__get_data_type(he, arch, di_cache.dbg, dl, 2725 + &he->mem_type_off); 2726 + if (mem_type) 2727 + return mem_type == NO_TYPE ? NULL : mem_type; 2880 2728 2881 2729 /* 2882 2730 * Some instructions can be fused and the actual memory access came ··· 2829 2811 } 2830 2812 2831 2813 ann_data_stat.no_mem_ops++; 2832 - istat->bad++; 2814 + istat = annotate_data_stat(&ann_insn_stat, dl->ins.name); 2815 + if (istat) 2816 + istat->bad++; 2833 2817 return NULL; 2834 2818 } 2835 2819