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: Add --code-with-type option.

This option is to show data type info in the regular (code) annotation.
It tries to find data type for each (memory) instruction in the
function. It'd be useful to see function-level memory access pattern
and also to debug the data type profiling result.

The output would be added at the end of the line and have "# data-type:"
prefix.

For now, it only works with --stdio mode for simplicity. I can work on
enabling it for TUI later.

$ perf annotate --stdio --code-with-type
Percent | Source code & Disassembly of vmlinux for cpu/mem-loads/ppk (253 samples, percent: local period)
---------------------------------------------------------------------------------------------------------------
: 0 0xffffffff81baa000 <check_preemption_disabled>:
0.00 : ffffffff81baa000: pushq %r12 # data-type: (stack operation)
0.00 : ffffffff81baa002: pushq %rbp # data-type: (stack operation)
0.00 : ffffffff81baa003: pushq %rbx # data-type: (stack operation)
0.00 : ffffffff81baa004: subq $0x8, %rsp
18.00 : ffffffff81baa008: movl %gs:0x7e48893d(%rip), %ebx # 0x3294c <pcpu_hot+0xc> # data-type: struct pcpu_hot +0xc (cpu_number)
12.58 : ffffffff81baa00f: movl %gs:0x7e488932(%rip), %eax # 0x32948 <pcpu_hot+0x8> # data-type: struct pcpu_hot +0x8 (preempt_count)
0.00 : ffffffff81baa016: testl $0x7fffffff, %eax
0.00 : ffffffff81baa01b: je 0xffffffff81baa02c <check_preemption_disabled+0x2c>
0.00 : ffffffff81baa01d: addq $0x8, %rsp
0.00 : ffffffff81baa021: movl %ebx, %eax
14.19 : ffffffff81baa023: popq %rbx # data-type: (stack operation)
18.86 : ffffffff81baa024: popq %rbp # data-type: (stack operation)
12.10 : ffffffff81baa025: popq %r12 # data-type: (stack operation)
17.78 : ffffffff81baa027: jmp 0xffffffff81bc1170 <__x86_return_thunk>
6.49 : ffffffff81baa02c: callq *0xc9139e(%rip) # 0xffffffff8283b3d0 <pv_ops+0xf0> # data-type: (stack operation)
0.00 : ffffffff81baa032: testb $0x2, %ah
0.00 : ffffffff81baa035: je 0xffffffff81baa01d <check_preemption_disabled+0x1d>
0.00 : ffffffff81baa037: movq %rdi, %rbp
0.00 : ffffffff81baa03a: movq %gs:0x32940, %rax # data-type: struct pcpu_hot +0 (current_task)
0.00 : ffffffff81baa043: testb $0x4, 0x2f(%rax) # data-type: struct task_struct +0x2f (flags)
0.00 : ffffffff81baa047: je 0xffffffff81baa052 <check_preemption_disabled+0x52>
0.00 : ffffffff81baa049: cmpl $0x1, 0x3d0(%rax) # data-type: struct task_struct +0x3d0 (nr_cpus_allowed)
0.00 : ffffffff81baa050: je 0xffffffff81baa01d <check_preemption_disabled+0x1d>
0.00 : ffffffff81baa052: movq %gs:0x32940, %r12 # data-type: struct pcpu_hot +0 (current_task)
0.00 : ffffffff81baa05b: cmpw $0x0, 0x7f0(%r12) # data-type: struct task_struct +0x7f0 (migration_disabled)
0.00 : ffffffff81baa065: movq %rsi, (%rsp)
0.00 : ffffffff81baa069: jne 0xffffffff81baa01d <check_preemption_disabled+0x1d>
0.00 : ffffffff81baa06b: movl 0xe8dd13(%rip), %eax # 0xffffffff82a37d84 <system_state> # data-type: enum system_states +0
0.00 : ffffffff81baa071: testl %eax, %eax
0.00 : ffffffff81baa073: je 0xffffffff81baa01d <check_preemption_disabled+0x1d>
0.00 : ffffffff81baa075: incl %gs:0x7e4888cc(%rip) # 0x32948 <pcpu_hot+0x8> # data-type: struct pcpu_hot +0x8 (preempt_count)
0.00 : ffffffff81baa07c: movq $-0x7e14a100, %rdi
0.00 : ffffffff81baa083: callq 0xffffffff81148c40 <__printk_ratelimit> # data-type: (stack operation)
0.00 : ffffffff81baa088: testl %eax, %eax
0.00 : ffffffff81baa08a: je 0xffffffff81baa0d5 <check_preemption_disabled+0xd5>
0.00 : ffffffff81baa08c: movl 0x958(%r12), %r9d # data-type: struct task_struct +0x958 (pid)
0.00 : ffffffff81baa094: movq (%rsp), %rdx # data-type: char* +0
0.00 : ffffffff81baa098: movq %rbp, %rsi
0.00 : ffffffff81baa09b: leaq 0xb88(%r12), %r8 # data-type: struct task_struct +0xb88 (comm)
0.00 : ffffffff81baa0a3: movl %gs:0x7e48889e(%rip), %ecx # 0x32948 <pcpu_hot+0x8> # data-type: struct pcpu_hot +0x8 (preempt_count)
0.00 : ffffffff81baa0aa: andl $0x7fffffff, %ecx
0.00 : ffffffff81baa0b0: movq $-0x7dd3cdf0, %rdi
0.00 : ffffffff81baa0b7: subl $0x1, %ecx
0.00 : ffffffff81baa0ba: callq 0xffffffff81149340 <_printk> # data-type: (stack operation)
0.00 : ffffffff81baa0bf: movq 0x20(%rsp), %rsi
0.00 : ffffffff81baa0c4: movq $-0x7ddb8c7e, %rdi
0.00 : ffffffff81baa0cb: callq 0xffffffff81149340 <_printk> # data-type: (stack operation)
0.00 : ffffffff81baa0d0: callq 0xffffffff81b7ab60 <dump_stack> # data-type: (stack operation)
0.00 : ffffffff81baa0d5: decl %gs:0x7e48886c(%rip) # 0x32948 <pcpu_hot+0x8> # data-type: struct pcpu_hot +0x8 (preempt_count)
0.00 : ffffffff81baa0dc: jmp 0xffffffff81baa01d <check_preemption_disabled+0x1d>

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

+13
+4
tools/perf/Documentation/perf-annotate.txt
··· 168 168 --skip-empty:: 169 169 Do not display empty (or dummy) events. 170 170 171 + --code-with-type:: 172 + Show data type info in code annotation (for memory instructions only). 173 + Currently it only works with --stdio option. 174 + 171 175 172 176 SEE ALSO 173 177 --------
+9
tools/perf/builtin-annotate.c
··· 788 788 "Show instruction stats for the data type annotation"), 789 789 OPT_BOOLEAN(0, "skip-empty", &symbol_conf.skip_empty, 790 790 "Do not display empty (or dummy) events in the output"), 791 + OPT_BOOLEAN(0, "code-with-type", &annotate_opts.code_with_type, 792 + "Show data type info in code annotation (memory instructions only)"), 791 793 OPT_END() 792 794 }; 793 795 int ret; ··· 915 913 annotate_opts.annotate_src = false; 916 914 symbol_conf.annotate_data_member = true; 917 915 symbol_conf.annotate_data_sample = true; 916 + } else if (annotate_opts.code_with_type) { 917 + symbol_conf.annotate_data_member = true; 918 + 919 + if (!annotate.use_stdio) { 920 + pr_err("--code-with-type only works with --stdio.\n"); 921 + goto out_delete; 922 + } 918 923 } 919 924 920 925 setup_browser(true);