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

perf report: Add 'symoff' sort key

The symoff sort key is to print symbol and offset of sample. This is
useful for data type profiling to show exact instruction in the function
which refers the data.

$ perf report -s type,sym,typeoff,symoff --hierarchy
...
# Overhead Data Type / Symbol / Data Type Offset / Symbol Offset
# .............. .....................................................
#
1.23% struct cfs_rq
0.84% update_blocked_averages
0.19% struct cfs_rq +336 (leaf_cfs_rq_list.next)
0.19% [k] update_blocked_averages+0x96
0.19% struct cfs_rq +0 (load.weight)
0.14% [k] update_blocked_averages+0x104
0.04% [k] update_blocked_averages+0x31c
0.17% struct cfs_rq +404 (throttle_count)
0.12% [k] update_blocked_averages+0x9d
0.05% [k] update_blocked_averages+0x1f9
0.08% struct cfs_rq +272 (propagate)
0.07% [k] update_blocked_averages+0x3d3
0.02% [k] update_blocked_averages+0x45b
...

Committer testing:

# perf report --stdio -s type,typeoff,symoff
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 4 of event 'cpu_atom/mem-loads,ldlat=30/P'
# Event count (approx.): 7
#
# Overhead Data Type Data Type Offset Symbol Offset
# ........ ......... ................ .............
#
42.86% struct list_head struct list_head +8 (prev) [k] __list_del_entry_valid_or_report+0x7
28.57% (unknown) (unknown) +0 (no field) [.] _nl_intern_locale_data+0x25
14.29% char char +0 (no field) [k] strncpy_from_user+0xa5
14.29% (unknown) (unknown) +0 (no field) [.] _dl_lookup_symbol_x+0x50

#
# (Tip: To change sampling frequency to 100 Hz: perf record -F 100)
#

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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-14-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
e2c1c8ff 871304a7

+50
+1
tools/perf/Documentation/perf-report.txt
··· 120 120 - simd: Flags describing a SIMD operation. "e" for empty Arm SVE predicate. "p" for partial Arm SVE predicate 121 121 - type: Data type of sample memory access. 122 122 - typeoff: Offset in the data type of sample memory access. 123 + - symoff: Offset in the symbol. 123 124 124 125 By default, comm, dso and symbol keys are used. 125 126 (i.e. --sort comm,dso,symbol)
+1
tools/perf/util/hist.h
··· 84 84 HISTC_SIMD, 85 85 HISTC_TYPE, 86 86 HISTC_TYPE_OFFSET, 87 + HISTC_SYMBOL_OFFSET, 87 88 HISTC_NR_COLS, /* Last entry */ 88 89 }; 89 90
+47
tools/perf/util/sort.c
··· 419 419 .se_width_idx = HISTC_SYMBOL, 420 420 }; 421 421 422 + /* --sort symoff */ 423 + 424 + static int64_t 425 + sort__symoff_cmp(struct hist_entry *left, struct hist_entry *right) 426 + { 427 + int64_t ret; 428 + 429 + ret = sort__sym_cmp(left, right); 430 + if (ret) 431 + return ret; 432 + 433 + return left->ip - right->ip; 434 + } 435 + 436 + static int64_t 437 + sort__symoff_sort(struct hist_entry *left, struct hist_entry *right) 438 + { 439 + int64_t ret; 440 + 441 + ret = sort__sym_sort(left, right); 442 + if (ret) 443 + return ret; 444 + 445 + return left->ip - right->ip; 446 + } 447 + 448 + static int 449 + hist_entry__symoff_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) 450 + { 451 + struct symbol *sym = he->ms.sym; 452 + 453 + if (sym == NULL) 454 + return repsep_snprintf(bf, size, "[%c] %-#.*llx", he->level, width - 4, he->ip); 455 + 456 + return repsep_snprintf(bf, size, "[%c] %s+0x%llx", he->level, sym->name, he->ip - sym->start); 457 + } 458 + 459 + struct sort_entry sort_sym_offset = { 460 + .se_header = "Symbol Offset", 461 + .se_cmp = sort__symoff_cmp, 462 + .se_sort = sort__symoff_sort, 463 + .se_snprintf = hist_entry__symoff_snprintf, 464 + .se_filter = hist_entry__sym_filter, 465 + .se_width_idx = HISTC_SYMBOL_OFFSET, 466 + }; 467 + 422 468 /* --sort srcline */ 423 469 424 470 char *hist_entry__srcline(struct hist_entry *he) ··· 2381 2335 DIM(SORT_SIMD, "simd", sort_simd), 2382 2336 DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type), 2383 2337 DIM(SORT_ANNOTATE_DATA_TYPE_OFFSET, "typeoff", sort_type_offset), 2338 + DIM(SORT_SYM_OFFSET, "symoff", sort_sym_offset), 2384 2339 }; 2385 2340 2386 2341 #undef DIM
+1
tools/perf/util/sort.h
··· 249 249 SORT_SIMD, 250 250 SORT_ANNOTATE_DATA_TYPE, 251 251 SORT_ANNOTATE_DATA_TYPE_OFFSET, 252 + SORT_SYM_OFFSET, 252 253 253 254 /* branch stack specific sort keys */ 254 255 __SORT_BRANCH_STACK,