Commit Graph

9632 Commits

Author SHA1 Message Date
Namhyung Kim
873a83731f perf annotate: Skip DSOs not found
In some data file, I see the following messages repeated.  It seems it
doesn't have DSOs in the system and the dso->binary_type is set to
DSO_BINARY_TYPE__NOT_FOUND.  Let's skip them to avoid the followings.

  No output from objdump  --start-address=0x0000000000000000 --stop-address=0x00000000000000d4  -d --no-show-raw-insn       -C "$1"
  Error running objdump  --start-address=0x0000000000000000 --stop-address=0x0000000000000631  -d --no-show-raw-insn       -C "$1"
  ...

Closes: https://lore.kernel.org/linux-perf-users/15e1a2847b8cebab4de57fc68e033086aa6980ce.camel@yandex.ru/
Reported-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240410185117.1987239-1-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:06 -03:00
Namhyung Kim
6cdd977ec2 perf report: Do not collect sample histogram unnecessarily
The data type profiling alone doesn't need the sample histogram for
functions.  It only needs the histogram for the types.

Let's remove the condition in the report_callback to check if data type
profiling is selected and make sure the annotation has the 'struct
annotated_source' instantiated before calling symbol__disassemble().

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240411033256.2099646-8-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:06 -03:00
Namhyung Kim
d001c7a7f4 perf annotate-data: Add hist_entry__annotate_data_tui()
Support data type profiling output on TUI.

Testing from Arnaldo:

First make sure that the debug information for your workload binaries
in embedded in them by building it with '-g' or install the debuginfo
packages, since our workload is 'find':

  root@number:~# type find
  find is hashed (/usr/bin/find)
  root@number:~# rpm -qf /usr/bin/find
  findutils-4.9.0-5.fc39.x86_64
  root@number:~# dnf debuginfo-install findutils
  <SNIP>
  root@number:~#

Then collect some data:

  root@number:~# echo 1 > /proc/sys/vm/drop_caches
  root@number:~# perf mem record find / > /dev/null
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.331 MB perf.data (3982 samples) ]
  root@number:~#

Finally do data-type annotation with the following command, that will
default, as 'perf report' to the --tui mode, with lines colored to
highlight the hotspots, etc.

  root@number:~# perf annotate --data-type
  Annotate type: 'struct predicate' (58 samples)
      Percent     Offset       Size  Field
       100.00          0        312  struct predicate {
         0.00          0          8      PRED_FUNC        pred_func;
         0.00          8          8      char*    p_name;
         0.00         16          4      enum predicate_type      p_type;
         0.00         20          4      enum predicate_precedence        p_prec;
         0.00         24          1      _Bool    side_effects;
         0.00         25          1      _Bool    no_default_print;
         0.00         26          1      _Bool    need_stat;
         0.00         27          1      _Bool    need_type;
         0.00         28          1      _Bool    need_inum;
         0.00         32          4      enum EvaluationCost      p_cost;
         0.00         36          4      float    est_success_rate;
         0.00         40          1      _Bool    literal_control_chars;
         0.00         41          1      _Bool    artificial;
         0.00         48          8      char*    arg_text;
  <SNIP>

Reviewed-by: Ian Rogers <irogers@google.com>
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: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240411033256.2099646-5-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:06 -03:00
Namhyung Kim
9b561be15f perf annotate-data: Add hist_entry__annotate_data_tty()
And move the related code into util/annotate-data.c file.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240411033256.2099646-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:06 -03:00
Namhyung Kim
eb83348863 perf annotate-data: Skip sample histogram for stack canary
It's a pseudo data type and has no field.

Fixes: b3c95109c1 ("perf annotate-data: Add stack canary type")
Closes: https://lore.kernel.org/lkml/Zhb6jJneP36Z-or0@x1
Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com>
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: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240411033256.2099646-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:06 -03:00
James Clark
df12e21d4e perf map: Remove kernel map before updating start and end addresses
In a debug build there is validation that mmap lists are sorted when
taking a lock. In machine__update_kernel_mmap() the start and end
addresses are updated resulting in an unsorted list before the map is
removed from the list. When the map is removed, the lock is taken which
triggers the validation and the failure:

  $ perf test "object code reading"
  --- start ---
  perf: util/maps.c:88: check_invariants: Assertion `map__start(prev) <= map__start(map)' failed.
  Aborted

Fix it by updating the addresses after removal, but before insertion.
The bug depends on the ordering and type of debug info on the system and
doesn't reproduce everywhere.

Fixes: 659ad3492b ("perf maps: Switch from rbtree to lazily sorted array for addresses")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: James Clark <james.clark@arm.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Spoorthy S <spoorts2@in.ibm.com>
Link: https://lore.kernel.org/r/20240410103458.813656-4-james.clark@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:06 -03:00
Ian Rogers
4b5ee6db2d perf metrics: Remove the "No_group" metric group
Rather than place metrics without a metric group in "No_group" place
them in a a metric group that is their name. Still allow such metrics
to be selected if "No_group" is passed, this change just impacts perf
list.

Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240403164636.3429091-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:05 -03:00
Namhyung Kim
0235abd89f perf annotate: Get rid of symbol__ensure_annotate()
Now symbol__annotate() is reentrant and it doesn't need to remove
non-instruction lines.  Let's get rid of symbol__ensure_annotate() and
call symbol__annotate() directly.  Also we can use it to get the arch
pointer instead of calling evsel__get_arch() directly.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240405211800.1412920-5-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:05 -03:00
Namhyung Kim
879ebf3c83 perf annotate-data: Do not delete non-asm lines
For data type profiling, it removed non-instruction lines from the list
of annotation lines.  It was to simplify the implementation dealing with
instructions like to calculate the PC-relative address and to search the
shortest path to the target instruction or basic block.

But it means that it removes all the comments and debug information in
the annotate output like source file name and line numbers.  To support
both code annotation and data type annotation, it'd be better to keep
the non-instruction lines as well.

So this change is to skip those lines during the data type profiling
and to display them in the normal perf annotate output.

No function changes intended (other than having more lines).

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240405211800.1412920-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:05 -03:00
Namhyung Kim
657852135d perf annotate-data: Fix global variable lookup
The recent change in the global variable handling added a bug to miss
setting the return value even if it found a data type.  Also add the
type name in the debug message.

Fixes: 1ebb5e17ef ("perf annotate-data: Add get_global_var_type()")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240405211800.1412920-3-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-12 12:02:05 -03:00
Namhyung Kim
f3408580ba perf lock contention: Add a missing NULL check
I got a report for a failure in BPF verifier on a recent kernel with
perf lock contention command.  It checks task->sighand->siglock without
checking if sighand is NULL or not.  Let's add one.

  ; if (&curr->sighand->siglock == (void *)lock)
  265: (79) r1 = *(u64 *)(r0 +2624)     ; frame1: R0_w=trusted_ptr_task_struct(off=0,imm=0)
                                        ;         R1_w=rcu_ptr_or_null_sighand_struct(off=0,imm=0)
  266: (b7) r2 = 0                      ; frame1: R2_w=0
  267: (0f) r1 += r2
  R1 pointer arithmetic on rcu_ptr_or_null_ prohibited, null-check it first
  processed 164 insns (limit 1000000) max_states_per_insn 1 total_states 15 peak_states 15 mark_read 5
  -- END PROG LOAD LOG --
  libbpf: prog 'contention_end': failed to load: -13
  libbpf: failed to load object 'lock_contention_bpf'
  libbpf: failed to load BPF skeleton 'lock_contention_bpf': -13
  Failed to load lock-contention BPF skeleton
  lock contention BPF setup failed
  lock contention did not detect any lock contention

Fixes: 1811e82767 ("perf lock contention: Track and show siglock with address")
Reviewed-by: Ian Rogers <irogers@google.com>
Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Song Liu <song@kernel.org>
Cc: bpf@vger.kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240409225542.1870999-1-namhyung@kernel.org
2024-04-11 10:30:06 -07:00
Namhyung Kim
2b8dbf69ec perf annotate: Make sure to call symbol__annotate2() in TUI
The symbol__annotate2() initializes some data structures needed by TUI.
It has a logic to prevent calling it multiple times by checking if it
has the annotated source.  But data type profiling uses a different
code (symbol__annotate) to allocate the annotated lines in advance.
So TUI missed to call symbol__annotate2() when it shows the annotation
browser.

Make symbol__annotate() reentrant and handle that situation properly.
This fixes a crash in the annotation browser started by perf report in
TUI like below.

  $ perf report -s type,sym --tui
  # and press 'a' key and then move down

Fixes: 81e57deec3 ("perf report: Support data type profiling")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240405211800.1412920-2-namhyung@kernel.org
2024-04-11 10:14:58 -07:00
Namhyung Kim
8c004c7a60 perf annotate: Move 'start' field struct to 'struct annotated_source'
It's only used in 'perf annotate' output which means functions with actual
samples.  No need to consume memory for every symbol ('struct annotation').

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-10-namhyung@kernel.org
Cc: Ian Rogers <irogers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: LKML <linux-kernel@vger.kernel.org>
Cc:  <linux-perf-users@vger.kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
6f94a72d45 perf annotate: Move nr_events struct to 'struct annotated_source'
It's only used in 'perf annotate' output which means functions with actual
samples.  No need to consume memory for every symbol ('struct annotation').

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-9-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
f6b18ababa perf annotate: Move 'max_jump_sources' struct to 'struct annotated_source'
It's only used in 'perf annotate' output which means functions with actual
samples.  No need to consume memory for every symbol ('struct annotation').

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-8-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
a46acc4567 perf annotate: Move 'widths' struct to 'struct annotated_source'
It's only used in 'perf annotate' output which means functions with
actual samples.  No need to consume memory for every symbol
('struct annotation').

Also move the 'max_line_len' field into it as it's related.

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-7-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
cee9b86043 perf annotate: Get rid of offsets array
The struct annotated_source.offsets[] is to save pointers to
annotation_line at each offset.  We can use annotated_source__get_line()
helper instead so let's get rid of the array.

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-6-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
0c053ed273 perf annotate: Check annotation lines more efficiently
In some places, it checks annotated (disasm) lines for each byte.  But
as it already has a list of disasm lines, it'd be better to traverse the
list entries instead of checking every offset with linear search (by
annotated_source__get_line() helper).

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-5-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
6f157d9af1 perf annotate: Introduce annotated_source__get_line()
It's a helper function to get annotation_line at the given offset
without using the offsets array.  The goal is to get rid of the
offsets array altogether.  It just does the linear search but I
think it's better to save memory as it won't be called in a hot
path.

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
bfd98ceb62 perf annotate: Staticize some local functions
I found annotation__mark_jump_targets(), annotation__set_offsets()
and annotation__init_column_widths() are only used in the same file.
Let's make them static.

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: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-3-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Namhyung Kim
aaf494cf48 perf annotate: Fix annotation_calc_lines() to pass correct address to get_srcline()
It should pass a proper address (i.e. suitable for objdump or addr2line)
to get_srcline() in order to work correctly.  It used to pass an address
with map__rip_2objdump() as the second argument but later it's changed
to use notes->start.  It's ok in normal cases but it can be changed when
annotate_opts.full_addr is set.  So let's convert the address directly
instead of using the notes->start.

Also the last argument is an IP to print symbol offset if requested.  So
it should pass symbol-relative address.

Fixes: 7d18a824b5 ("perf annotate: Toggle full address <-> offset display")
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: Kan Liang <kan.liang@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240404175716.1225482-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:43:20 -03:00
Adrian Hunter
218c200f67 perf script: Consolidate capstone print functions
Consolidate capstone print functions, to reduce duplication. Amend call
sites to use a file pointer for output, which is consistent with most
perf tools print functions. Add print_opts with an option to print also
the hex value of a resolved symbol+offset.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20240401210925.209671-4-ak@linux.intel.com
Signed-off-by: Andi Kleen <ak@linux.intel.com>
[ Added missing inttypes.h include to use PRIx64 in util/print_insn.c ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-08 17:42:27 -03:00
Andi Kleen
d812044688 perf script: Add capstone support for '-F +brstackdisasm'
Support capstone output for the '-F +brstackinsn' branch dump.

The new output is enabled with the new field 'brstackdisasm'.

This was possible before with --xed, but now also allow it for users
that don't have xed using the builtin capstone support.

Before:

  perf record -b emacs -Q --batch '()'
  perf script -F +brstackinsn
  ...
            emacs   55778 1814366.755945:     151564 cycles:P:      7f0ab2d17192 intel_check_word.constprop.0+0x162 (/usr/lib64/ld-linux-x86-64.s>        intel_check_word.constprop.0+237:
          00007f0ab2d1711d        insn: 75 e6                     # PRED 3 cycles [3]
          00007f0ab2d17105        insn: 73 51
          00007f0ab2d17107        insn: 48 89 c1
          00007f0ab2d1710a        insn: 48 39 ca
          00007f0ab2d1710d        insn: 73 96
          00007f0ab2d1710f        insn: 48 8d 04 11
          00007f0ab2d17113        insn: 48 d1 e8
          00007f0ab2d17116        insn: 49 8d 34 c1
          00007f0ab2d1711a        insn: 44 3a 06
          00007f0ab2d1711d        insn: 75 e6                     # PRED 3 cycles [6] 3.00 IPC
          00007f0ab2d17105        insn: 73 51                     # PRED 1 cycles [7] 1.00 IPC
          00007f0ab2d17158        insn: 48 8d 50 01
          00007f0ab2d1715c        insn: eb 92                     # PRED 1 cycles [8] 2.00 IPC
          00007f0ab2d170f0        insn: 48 39 ca
          00007f0ab2d170f3        insn: 73 b0                     # PRED 1 cycles [9] 2.00 IPC

After (perf must be compiled with capstone):

  perf script -F +brstackdisasm

  ...
             emacs   55778 1814366.755945:     151564 cycles:P:      7f0ab2d17192 intel_check_word.constprop.0+0x162 (/usr/lib64/ld-linux-x86-64.s>        intel_check_word.constprop.0+237:
          00007f0ab2d1711d        jne intel_check_word.constprop.0+0xd5   # PRED 3 cycles [3]
          00007f0ab2d17105        jae intel_check_word.constprop.0+0x128
          00007f0ab2d17107        movq %rax, %rcx
          00007f0ab2d1710a        cmpq %rcx, %rdx
          00007f0ab2d1710d        jae intel_check_word.constprop.0+0x75
          00007f0ab2d1710f        leaq (%rcx, %rdx), %rax
          00007f0ab2d17113        shrq $1, %rax
          00007f0ab2d17116        leaq (%r9, %rax, 8), %rsi
          00007f0ab2d1711a        cmpb (%rsi), %r8b
          00007f0ab2d1711d        jne intel_check_word.constprop.0+0xd5   # PRED 3 cycles [6] 3.00 IPC
          00007f0ab2d17105        jae intel_check_word.constprop.0+0x128  # PRED 1 cycles [7] 1.00 IPC
          00007f0ab2d17158        leaq 1(%rax), %rdx
          00007f0ab2d1715c        jmp intel_check_word.constprop.0+0xc0   # PRED 1 cycles [8] 2.00 IPC
          00007f0ab2d170f0        cmpq %rcx, %rdx
          00007f0ab2d170f3        jae intel_check_word.constprop.0+0x75   # PRED 1 cycles [9] 2.00 IPC

Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Link: https://lore.kernel.org/r/20240401210925.209671-3-ak@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-05 10:43:07 -03:00
Andi Kleen
38ab60132b perf script: Support 32bit code under 64bit OS with capstone
Use the DSO to resolve whether an IP is 32bit or 64bit and use that to
configure capstone to the correct mode. This allows to correctly
disassemble 32bit code under a 64bit OS.

  % cat > loop.c
  volatile int var;
  int main(void)
  {
  	int i;
  	for (i = 0; i < 100000; i++)
  		var++;
  }
  % gcc -m32 -o loop loop.c
  % perf record -e cycles:u ./loop
  % perf script -F +disasm
    loop   82665 1833176.618023:      1 cycles:u:   f7eed500 _start+0x0 (/usr/lib/ld-linux.so.2)   movl %esp, %eax
    loop   82665 1833176.618029:      1 cycles:u:   f7eed500 _start+0x0 (/usr/lib/ld-linux.so.2)   movl %esp, %eax
    loop   82665 1833176.618031:      7 cycles:u:   f7eed500 _start+0x0 (/usr/lib/ld-linux.so.2)   movl %esp, %eax
    loop   82665 1833176.618034:     91 cycles:u:   f7eed500 _start+0x0 (/usr/lib/ld-linux.so.2)   movl %esp, %eax
    loop   82665 1833176.618036:   1242 cycles:u:   f7eed500 _start+0x0 (/usr/lib/ld-linux.so.2)   movl %esp, %eax

Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Acked-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Link: https://lore.kernel.org/r/20240401210925.209671-2-ak@linux.intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-05 09:42:36 -03:00
Arnaldo Carvalho de Melo
b6347cb5e0 perf annotate: Initialize 'arch' variable not to trip some -Werror=maybe-uninitialized
In some older distros the build is failing due to
-Werror=maybe-uninitialized, in this case we know that this isn't the
case because 'arch' gets initialized by evsel__get_arch(), so make sure
it is initialized to NULL before returning from evsel__get_arch(), as
suggested by Ian Rogers.

E.g.:

    32    17.12 opensuse:15.5                 : FAIL gcc version 7.5.0 (SUSE Linux)
        util/annotate.c: In function 'hist_entry__get_data_type':
    util/annotate.c:2269:15: error: 'arch' may be used uninitialized in this function [-Werror=maybe-uninitialized]
      struct arch *arch;
                   ^~~~
    cc1: all warnings being treated as errors

      43     7.30 ubuntu:18.04-x-powerpc64el    : FAIL gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
    util/annotate.c: In function 'hist_entry__get_data_type':
    util/annotate.c:2351:36: error: 'arch' may be used uninitialized in this function [-Werror=maybe-uninitialized]
       if (map__dso(ms->map)->kernel && arch__is(arch, "x86") &&
                                        ^~~~~~~~~~~~~~~~~~~~~
    cc1: all warnings being treated as errors

Suggested-by: Ian Rogers <irogers@google.com>
Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/lkml/CAP-5=fUqtjxAsmdGrnkjhUTLHs-JvV10TtxyocpYDJK_+LYTiQ@mail.gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-03 18:05:19 -03:00
Namhyung Kim
92dfc59463 perf annotate: Add symbol name when using capstone
This is to keep the existing behavior with objdump.  It needs to show
symbol information of global variables like below:

   Percent |      Source code & Disassembly of elf for cycles:P (1 samples, percent: local period)
  ------------------------------------------------------------------------------------------------
           : 0                0xffffffff81338f70 <vm_normal_page>:
      0.00 :   ffffffff81338f70:       endbr64
      0.00 :   ffffffff81338f74:       callq   0xffffffff81083a40
      0.00 :   ffffffff81338f79:       movq    %rdi, %r8
      0.00 :   ffffffff81338f7c:       movq    %rdx, %rdi
      0.00 :   ffffffff81338f7f:       callq   *0x17021c3(%rip)   # ffffffff82a3b148 <pv_ops+0x1e8>
      0.00 :   ffffffff81338f85:       movq    0xffbf3c(%rip), %rdx       # ffffffff82334ec8 <physical_mask>
      0.00 :   ffffffff81338f8c:       testq   %rax, %rax                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      0.00 :   ffffffff81338f8f:       je      0xffffffff81338fd0                         here
      0.00 :   ffffffff81338f91:       movq    %rax, %rcx
      0.00 :   ffffffff81338f94:       andl    $1, %ecx

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240329215812.537846-6-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-03 11:48:57 -03:00
Namhyung Kim
6d17edc113 perf annotate: Use libcapstone to disassemble
Now it can use the capstone library to disassemble the instructions.
Let's use that (if available) for perf annotate to speed up.  Currently
it only supports x86 architecture.  With this change I can see ~3x speed
up in data type profiling.

But note that capstone cannot give the source file and line number info.
For now, users should use the external objdump for that by specifying
the --objdump option explicitly.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240329215812.537846-5-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-03 11:48:57 -03:00
Namhyung Kim
98f69a573c perf annotate: Split out util/disasm.c
The util/annotate.c code has both disassembly and sample annotation
related codes.  Factor out the disasm part so that it can be handled
more easily.

No functional changes intended.

Committer notes:

Add missing include env.h, util.h, bpf-event.h and bpf-util.h to
disasm.c, to fix things like:

  util/disasm.c: In function ‘symbol__disassemble_bpf’:
  util/disasm.c:1203:9: error: implicit declaration of function ‘perf_exe’ [-Werror=implicit-function-declaration]
   1203 |         perf_exe(tpath, sizeof(tpath));
        |         ^~~~~~~~

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240329215812.537846-4-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-03 11:48:57 -03:00
Namhyung Kim
10adbf7776 perf annotate: Add and use ins__is_nop()
Likewise, add ins__is_nop() to check if the current instruction is NOP.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240329215812.537846-3-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-03 11:48:57 -03:00
Namhyung Kim
ad399baa06 perf annotate: Use ins__is_xxx() if possible
This is to prepare separation of disasm related code.  Use the public
ins API instead of checking the internal data structure.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240329215812.537846-2-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-04-03 11:48:56 -03:00
Alexander Lobakin
7d8296b250 bitops: make BYTES_TO_BITS() treewide-available
Avoid open-coding that simple expression each time by moving
BYTES_TO_BITS() from the probes code to <linux/bitops.h> to export
it to the rest of the kernel.
Simplify the macro while at it. `BITS_PER_LONG / sizeof(long)` always
equals to %BITS_PER_BYTE, regardless of the target architecture.
Do the same for the tools ecosystem as well (incl. its version of
bitops.h). The previous implementation had its implicit type of long,
while the new one is int, so adjust the format literal accordingly in
the perf code.

Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Acked-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2024-04-01 10:49:27 +01:00
Ian Rogers
b3ad832d8d perf dso: Reorder members to save space in 'struct dso'
Save 40 bytes and move from 8 to 7 cache lines. Make member dwfl
dependent on being a powerpc build. Squeeze bits of int/enum types
when appropriate. Remove holes/padding by reordering variables.

Before:

  struct dso {
          struct mutex               lock;                 /*     0    40 */
          struct list_head           node;                 /*    40    16 */
          struct rb_node             rb_node __attribute__((__aligned__(8))); /*    56    24 */
          /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
          struct rb_root *           root;                 /*    80     8 */
          struct rb_root_cached      symbols;              /*    88    16 */
          struct symbol * *          symbol_names;         /*   104     8 */
          size_t                     symbol_names_len;     /*   112     8 */
          struct rb_root_cached      inlined_nodes;        /*   120    16 */
          /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
          struct rb_root_cached      srclines;             /*   136    16 */
          struct {
                  u64                addr;                 /*   152     8 */
                  struct symbol *    symbol;               /*   160     8 */
          } last_find_result;                              /*   152    16 */
          void *                     a2l;                  /*   168     8 */
          char *                     symsrc_filename;      /*   176     8 */
          unsigned int               a2l_fails;            /*   184     4 */
          enum dso_space_type        kernel;               /*   188     4 */
          /* --- cacheline 3 boundary (192 bytes) --- */
          _Bool                      is_kmod;              /*   192     1 */

          /* XXX 3 bytes hole, try to pack */

          enum dso_swap_type         needs_swap;           /*   196     4 */
          enum dso_binary_type       symtab_type;          /*   200     4 */
          enum dso_binary_type       binary_type;          /*   204     4 */
          enum dso_load_errno        load_errno;           /*   208     4 */
          u8                         adjust_symbols:1;     /*   212: 0  1 */
          u8                         has_build_id:1;       /*   212: 1  1 */
          u8                         header_build_id:1;    /*   212: 2  1 */
          u8                         has_srcline:1;        /*   212: 3  1 */
          u8                         hit:1;                /*   212: 4  1 */
          u8                         annotate_warned:1;    /*   212: 5  1 */
          u8                         auxtrace_warned:1;    /*   212: 6  1 */
          u8                         short_name_allocated:1; /*   212: 7  1 */
          u8                         long_name_allocated:1; /*   213: 0  1 */
          u8                         is_64_bit:1;          /*   213: 1  1 */

          /* XXX 6 bits hole, try to pack */

          _Bool                      sorted_by_name;       /*   214     1 */
          _Bool                      loaded;               /*   215     1 */
          u8                         rel;                  /*   216     1 */

          /* XXX 7 bytes hole, try to pack */

          struct build_id            bid;                  /*   224    32 */
          /* --- cacheline 4 boundary (256 bytes) --- */
          u64                        text_offset;          /*   256     8 */
          u64                        text_end;             /*   264     8 */
          const char  *              short_name;           /*   272     8 */
          const char  *              long_name;            /*   280     8 */
          u16                        long_name_len;        /*   288     2 */
          u16                        short_name_len;       /*   290     2 */

          /* XXX 4 bytes hole, try to pack */

          void *                     dwfl;                 /*   296     8 */
          struct auxtrace_cache *    auxtrace_cache;       /*   304     8 */
          int                        comp;                 /*   312     4 */

          /* XXX 4 bytes hole, try to pack */

          /* --- cacheline 5 boundary (320 bytes) --- */
          struct {
                  struct rb_root     cache;                /*   320     8 */
                  int                fd;                   /*   328     4 */
                  int                status;               /*   332     4 */
                  u32                status_seen;          /*   336     4 */

                  /* XXX 4 bytes hole, try to pack */

                  u64                file_size;            /*   344     8 */
                  struct list_head   open_entry;           /*   352    16 */
                  u64                elf_base_addr;        /*   368     8 */
                  u64                debug_frame_offset;   /*   376     8 */
                  /* --- cacheline 6 boundary (384 bytes) --- */
                  u64                eh_frame_hdr_addr;    /*   384     8 */
                  u64                eh_frame_hdr_offset;  /*   392     8 */
          } data;                                          /*   320    80 */
          struct {
                  u32                id;                   /*   400     4 */
                  u32                sub_id;               /*   404     4 */
                  struct perf_env *  env;                  /*   408     8 */
          } bpf_prog;                                      /*   400    16 */
          union {
                  void *             priv;                 /*   416     8 */
                  u64                db_id;                /*   416     8 */
          };                                               /*   416     8 */
          struct nsinfo *            nsinfo;               /*   424     8 */
          struct dso_id              id;                   /*   432    24 */
          /* --- cacheline 7 boundary (448 bytes) was 8 bytes ago --- */
          refcount_t                 refcnt;               /*   456     4 */
          char                       name[];               /*   460     0 */

          /* size: 464, cachelines: 8, members: 49 */
          /* sum members: 440, holes: 4, sum holes: 18 */
          /* sum bitfield members: 10 bits, bit holes: 1, sum bit holes: 6 bits */
          /* padding: 4 */
          /* forced alignments: 1 */
          /* last cacheline: 16 bytes */
  } __attribute__((__aligned__(8)));

After:

  struct dso {
          struct mutex               lock;                 /*     0    40 */
          struct list_head           node;                 /*    40    16 */
          struct rb_node             rb_node __attribute__((__aligned__(8))); /*    56    24 */
          /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
          struct rb_root *           root;                 /*    80     8 */
          struct rb_root_cached      symbols;              /*    88    16 */
          struct symbol * *          symbol_names;         /*   104     8 */
          size_t                     symbol_names_len;     /*   112     8 */
          struct rb_root_cached      inlined_nodes;        /*   120    16 */
          /* --- cacheline 2 boundary (128 bytes) was 8 bytes ago --- */
          struct rb_root_cached      srclines;             /*   136    16 */
          struct {
                  u64                addr;                 /*   152     8 */
                  struct symbol *    symbol;               /*   160     8 */
          } last_find_result;                              /*   152    16 */
          struct build_id            bid;                  /*   168    32 */
          /* --- cacheline 3 boundary (192 bytes) was 8 bytes ago --- */
          u64                        text_offset;          /*   200     8 */
          u64                        text_end;             /*   208     8 */
          const char  *              short_name;           /*   216     8 */
          const char  *              long_name;            /*   224     8 */
          void *                     a2l;                  /*   232     8 */
          char *                     symsrc_filename;      /*   240     8 */
          struct nsinfo *            nsinfo;               /*   248     8 */
          /* --- cacheline 4 boundary (256 bytes) --- */
          struct auxtrace_cache *    auxtrace_cache;       /*   256     8 */
          union {
                  void *             priv;                 /*   264     8 */
                  u64                db_id;                /*   264     8 */
          };                                               /*   264     8 */
          struct {
                  struct perf_env *  env;                  /*   272     8 */
                  u32                id;                   /*   280     4 */
                  u32                sub_id;               /*   284     4 */
          } bpf_prog;                                      /*   272    16 */
          struct {
                  struct rb_root     cache;                /*   288     8 */
                  struct list_head   open_entry;           /*   296    16 */
                  u64                file_size;            /*   312     8 */
                  /* --- cacheline 5 boundary (320 bytes) --- */
                  u64                elf_base_addr;        /*   320     8 */
                  u64                debug_frame_offset;   /*   328     8 */
                  u64                eh_frame_hdr_addr;    /*   336     8 */
                  u64                eh_frame_hdr_offset;  /*   344     8 */
                  int                fd;                   /*   352     4 */
                  int                status;               /*   356     4 */
                  u32                status_seen;          /*   360     4 */
          } data;                                          /*   288    80 */

          /* XXX last struct has 4 bytes of padding */

          struct dso_id              id;                   /*   368    24 */
          /* --- cacheline 6 boundary (384 bytes) was 8 bytes ago --- */
          unsigned int               a2l_fails;            /*   392     4 */
          int                        comp;                 /*   396     4 */
          refcount_t                 refcnt;               /*   400     4 */
          enum dso_load_errno        load_errno;           /*   404     4 */
          u16                        long_name_len;        /*   408     2 */
          u16                        short_name_len;       /*   410     2 */
          enum dso_binary_type       symtab_type:8;        /*   412: 0  4 */
          enum dso_binary_type       binary_type:8;        /*   412: 8  4 */
          enum dso_space_type        kernel:2;             /*   412:16  4 */
          enum dso_swap_type         needs_swap:2;         /*   412:18  4 */

          /* Bitfield combined with next fields */

          _Bool                      is_kmod:1;            /*   414: 4  1 */
          u8                         adjust_symbols:1;     /*   414: 5  1 */
          u8                         has_build_id:1;       /*   414: 6  1 */
          u8                         header_build_id:1;    /*   414: 7  1 */
          u8                         has_srcline:1;        /*   415: 0  1 */
          u8                         hit:1;                /*   415: 1  1 */
          u8                         annotate_warned:1;    /*   415: 2  1 */
          u8                         auxtrace_warned:1;    /*   415: 3  1 */
          u8                         short_name_allocated:1; /*   415: 4  1 */
          u8                         long_name_allocated:1; /*   415: 5  1 */
          u8                         is_64_bit:1;          /*   415: 6  1 */

          /* XXX 1 bit hole, try to pack */

          _Bool                      sorted_by_name;       /*   416     1 */
          _Bool                      loaded;               /*   417     1 */
          u8                         rel;                  /*   418     1 */
          char                       name[];               /*   419     0 */

          /* size: 424, cachelines: 7, members: 48 */
          /* sum members: 415 */
          /* sum bitfield members: 31 bits, bit holes: 1, sum bit holes: 1 bits */
          /* padding: 5 */
          /* paddings: 1, sum paddings: 4 */
          /* forced alignments: 1 */
          /* last cacheline: 40 bytes */
  } __attribute__((__aligned__(8)));

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ahelenia Ziemiańska <nabijaczleweli@nabijaczleweli.xyz>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ben Gainey <ben.gainey@arm.com>
Cc: Changbin Du <changbin.du@huawei.com>
Cc: Chengen Du <chengen.du@canonical.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: K Prateek Nayak <kprateek.nayak@amd.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linux.dev>
Cc: Li Dong <lidong@vivo.com>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Markus Elfring <Markus.Elfring@web.de>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paran Lee <p4ranlee@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Song Liu <song@kernel.org>
Cc: Sun Haiyong <sunhaiyong@loongson.cn>
Cc: Yanteng Si <siyanteng@loongson.cn>
Cc: zhaimingbing <zhaimingbing@cmss.chinamobile.com>
Link: https://lore.kernel.org/r/20240321160300.1635121-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 20:44:35 -03:00
Anne Macedo
2a5049b75d perf lock contention: Trim backtrace by skipping traceiter functions
The 'perf lock contention' program currently shows the caller of the locks
as __traceiter_contention_begin+0x??. This caller can be ignored, as it is
from the traceiter itself. Instead, it should show the real callers for
the locks.

When fiddling with the --stack-skip parameter, the actual callers for
the locks start to show up. However, just ignore the
__traceiter_contention_begin and the __traceiter_contention_end symbols
so the actual callers will show up.

Before this patch is applied:

sudo perf lock con -a -b -- sleep 3
 contended   total wait     max wait     avg wait         type   caller

         8      2.33 s       2.28 s     291.18 ms     rwlock:W   __traceiter_contention_begin+0x44
         4      2.33 s       2.28 s     582.35 ms     rwlock:W   __traceiter_contention_begin+0x44
         7    140.30 ms     46.77 ms     20.04 ms     rwlock:W   __traceiter_contention_begin+0x44
         2     63.35 ms     33.76 ms     31.68 ms        mutex   trace_contention_begin+0x84
         2     46.74 ms     46.73 ms     23.37 ms     rwlock:W   __traceiter_contention_begin+0x44
         1     13.54 us     13.54 us     13.54 us        mutex   trace_contention_begin+0x84
         1      3.67 us      3.67 us      3.67 us      rwsem:R   __traceiter_contention_begin+0x44

Before this patch is applied - using --stack-skip 5

sudo perf lock con --stack-skip 5 -a -b -- sleep 3
 contended   total wait     max wait     avg wait         type   caller

         2      2.24 s       2.24 s       1.12 s      rwlock:W   do_epoll_wait+0x5a0
         4      1.65 s     824.21 ms    412.08 ms     rwlock:W   do_exit+0x338
         2    824.35 ms    824.29 ms    412.17 ms     spinlock   get_signal+0x108
         2    824.14 ms    824.14 ms    412.07 ms     rwlock:W   release_task+0x68
         1     25.22 ms     25.22 ms     25.22 ms        mutex   cgroup_kn_lock_live+0x58
         1     24.71 us     24.71 us     24.71 us     spinlock   do_exit+0x44
         1     22.04 us     22.04 us     22.04 us      rwsem:R   lock_mm_and_find_vma+0xb0

After this patch is applied:

sudo ./perf lock con -a -b -- sleep 3
 contended   total wait     max wait     avg wait         type   caller

         4      4.13 s       2.07 s       1.03 s      rwlock:W   release_task+0x68
         2      2.07 s       2.07 s       1.03 s      rwlock:R   mm_update_next_owner+0x50
         2      2.07 s       2.07 s       1.03 s      rwlock:W   do_exit+0x338
         1     41.56 ms     41.56 ms     41.56 ms        mutex   cgroup_kn_lock_live+0x58
         2     36.12 us     18.83 us     18.06 us     rwlock:W   do_exit+0x338

Signed-off-by: Anne Macedo <retpolanne@posteo.net>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240319143629.3422590-1-retpolanne@posteo.net
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 20:44:35 -03:00
Arnaldo Carvalho de Melo
5810371519 perf probe: Add missing libgen.h header needed for using basename()
This prototype is obtained indirectly, by luck, from some other header
in probe-event.c in most systems, but recently exploded on alpine:edge:

   8    13.39 alpine:edge                   : FAIL gcc version 13.2.1 20240309 (Alpine 13.2.1_git20240309)
    util/probe-event.c: In function 'convert_exec_to_group':
    util/probe-event.c:225:16: error: implicit declaration of function 'basename' [-Werror=implicit-function-declaration]
      225 |         ptr1 = basename(exec_copy);
          |                ^~~~~~~~
    util/probe-event.c:225:14: error: assignment to 'char *' from 'int' makes pointer from integer without a cast [-Werror=int-conversion]
      225 |         ptr1 = basename(exec_copy);
          |              ^
    cc1: all warnings being treated as errors
    make[3]: *** [/git/perf-6.8.0/tools/build/Makefile.build:158: util] Error 2

Fix it by adding the libgen.h header where basename() is prototyped.

Fixes: fb7345bbf7 ("perf probe: Support basic dwarf-based operations on uprobe events")
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/lkml/
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 13:54:40 -03:00
Ian Rogers
7aea01eaf4 perf help: Lower levenshtein penality for deleting character
The levenshtein penalty for deleting a character was far higher than
subsituting or inserting a character. Lower the penalty to match that
of inserting a character.

Before:

  $ perf recccord
  perf: 'recccord' is not a perf-command. See 'perf --help'.
  $

After:

  $ perf recccord
  perf: 'recccord' is not a perf-command. See 'perf --help'.

  Did you mean this?
          record
  $

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240301201306.2680986-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 13:54:40 -03:00
Ian Rogers
f664d5159d perf tools: Suggest inbuilt commands for unknown command
The existing unknown command code looks for perf scripts like
perf-archive.sh and perf-iostat.sh, however, inbuilt commands aren't
suggested. Add the inbuilt commands so they may be suggested too.

Before:

  $ perf reccord
  perf: 'reccord' is not a perf-command. See 'perf --help'.
  $

After:

  $ perf reccord
  perf: 'reccord' is not a perf-command. See 'perf --help'.

  Did you mean this?
          record
  $

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20240301201306.2680986-1-irogers@google.com
[ Added some fixes from Ian to problems I noticed while testing ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 13:54:40 -03:00
Ian Rogers
67ee8e71da perf tools: Add/use PMU reverse lookup from config to name
Add perf_pmu__name_from_config that does a reverse lookup from a
config number to an alias name. The lookup is expensive as the config
is computed for every alias by filling in a perf_event_attr, but this
is only done when verbose output is enabled. The lookup also only
considers config, and not config1, config2 or config3.

An example of the output:

  $ perf stat -vv -e data_read true
  ...
  perf_event_attr:
    type                             24 (uncore_imc_free_running_0)
    size                             136
    config                           0x20ff (data_read)
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ...

Committer notes:

Fix the python binding build by adding dummies for not strictly
needed perf_pmu__name_from_config() and perf_pmus__find_by_type().

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20240308001915.4060155-7-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 13:53:45 -03:00
Ian Rogers
7093882067 perf tools: Use pmus to describe type from attribute
When dumping a perf_event_attr, use pmus to find the PMU and its name
by the type number. This allows dynamically added PMUs to be described.

Before:

  $ perf stat -vv -e data_read true
  ...
  perf_event_attr:
    type                             24
    size                             136
    config                           0x20ff
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ...

After:

  $ perf stat -vv -e data_read true
  ...
  perf_event_attr:
    type                             24 (uncore_imc_free_running_0)
    size                             136
    config                           0x20ff
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    exclude_guest                    1
  ...

However, it also means that when we have a PMU name we prefer it to a
hard coded name:

Before:

  $ perf stat -vv -e faults true
  ...
  perf_event_attr:
    type                             1 (PERF_TYPE_SOFTWARE)
    size                             136
    config                           0x2 (PERF_COUNT_SW_PAGE_FAULTS)
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    enable_on_exec                   1
    exclude_guest                    1
  ...

After:

  $ perf stat -vv -e faults true
  ...
  perf_event_attr:
    type                             1 (software)
    size                             136
    config                           0x2 (PERF_COUNT_SW_PAGE_FAULTS)
    sample_type                      IDENTIFIER
    read_format                      TOTAL_TIME_ENABLED|TOTAL_TIME_RUNNING
    disabled                         1
    inherit                          1
    enable_on_exec                   1
    exclude_guest                    1
  ...

It feels more consistent to do this, rather than only prefer a PMU
name when a hard coded name isn't available.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20240308001915.4060155-6-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Ian Rogers
4ccf3bb703 perf list: Give more details about raw event encodings
List all the PMUs, not just the first core one, and list real format
specifiers with value ranges.

Before:

  $ perf list
  ...
    rNNN                                               [Raw hardware event descriptor]
    cpu/t1=v1[,t2=v2,t3 ...]/modifier                  [Raw hardware event descriptor]
         [(see 'man perf-list' on how to encode it)]
    mem:<addr>[/len][:access]                          [Hardware breakpoint]
  ...

After:

  $ perf list
  ...
    rNNN                                               [Raw event descriptor]
    cpu/event=0..255,pc,edge,.../modifier              [Raw event descriptor]
         [(see 'man perf-list' or 'man perf-record' on how to encode it)]
    breakpoint//modifier                               [Raw event descriptor]
    cstate_core/event=0..0xffffffffffffffff/modifier   [Raw event descriptor]
    cstate_pkg/event=0..0xffffffffffffffff/modifier    [Raw event descriptor]
    i915/i915_eventid=0..0x1fffff/modifier             [Raw event descriptor]
    intel_bts//modifier                                [Raw event descriptor]
    intel_pt/ptw,event,cyc_thresh=0..15,.../modifier   [Raw event descriptor]
    kprobe/retprobe/modifier                           [Raw event descriptor]
    msr/event=0..0xffffffffffffffff/modifier           [Raw event descriptor]
    power/event=0..255/modifier                        [Raw event descriptor]
    software//modifier                                 [Raw event descriptor]
    tracepoint//modifier                               [Raw event descriptor]
    uncore_arb/event=0..255,edge,inv,.../modifier      [Raw event descriptor]
    uncore_cbox/event=0..255,edge,inv,.../modifier     [Raw event descriptor]
    uncore_clock/event=0..255/modifier                 [Raw event descriptor]
    uncore_imc_free_running/event=0..255,umask=0..255/modifier[Raw event descriptor]
    uprobe/ref_ctr_offset=0..0xffffffff,retprobe/modifier[Raw event descriptor]
    mem:<addr>[/len][:access]                          [Hardware breakpoint]
  ...

With '--details' provide more details on the formats encoding:

  cpu/event=0..255,pc,edge,.../modifier              [Raw event descriptor]
       [(see 'man perf-list' or 'man perf-record' on how to encode it)]
        cpu/event=0..255,pc,edge,offcore_rsp=0..0xffffffffffffffff,ldlat=0..0xffff,inv,
        umask=0..255,frontend=0..0xffffff,cmask=0..255,config=0..0xffffffffffffffff,
        config1=0..0xffffffffffffffff,config2=0..0xffffffffffffffff,config3=0..0xffffffffffffffff,
        name=string,period=number,freq=number,branch_type=(u|k|hv|any|...),time,
        call-graph=(fp|dwarf|lbr),stack-size=number,max-stack=number,nr=number,inherit,no-inherit,
        overwrite,no-overwrite,percore,aux-output,aux-sample-size=number/modifier
  breakpoint//modifier                               [Raw event descriptor]
        breakpoint//modifier
  cstate_core/event=0..0xffffffffffffffff/modifier   [Raw event descriptor]
        cstate_core/event=0..0xffffffffffffffff/modifier
  cstate_pkg/event=0..0xffffffffffffffff/modifier    [Raw event descriptor]
        cstate_pkg/event=0..0xffffffffffffffff/modifier
  i915/i915_eventid=0..0x1fffff/modifier             [Raw event descriptor]
        i915/i915_eventid=0..0x1fffff/modifier
  intel_bts//modifier                                [Raw event descriptor]
        intel_bts//modifier
  intel_pt/ptw,event,cyc_thresh=0..15,.../modifier   [Raw event descriptor]
        intel_pt/ptw,event,cyc_thresh=0..15,pt,notnt,branch,tsc,pwr_evt,fup_on_ptw,cyc,noretcomp,
        mtc,psb_period=0..15,mtc_period=0..15/modifier
  kprobe/retprobe/modifier                           [Raw event descriptor]
        kprobe/retprobe/modifier
  msr/event=0..0xffffffffffffffff/modifier           [Raw event descriptor]
        msr/event=0..0xffffffffffffffff/modifier
  power/event=0..255/modifier                        [Raw event descriptor]
        power/event=0..255/modifier
  software//modifier                                 [Raw event descriptor]
        software//modifier
  tracepoint//modifier                               [Raw event descriptor]
        tracepoint//modifier
  uncore_arb/event=0..255,edge,inv,.../modifier      [Raw event descriptor]
        uncore_arb/event=0..255,edge,inv,umask=0..255,cmask=0..31/modifier
  uncore_cbox/event=0..255,edge,inv,.../modifier     [Raw event descriptor]
        uncore_cbox/event=0..255,edge,inv,umask=0..255,cmask=0..31/modifier
  uncore_clock/event=0..255/modifier                 [Raw event descriptor]
        uncore_clock/event=0..255/modifier
  uncore_imc_free_running/event=0..255,umask=0..255/modifier[Raw event descriptor]
        uncore_imc_free_running/event=0..255,umask=0..255/modifier
  uprobe/ref_ctr_offset=0..0xffffffff,retprobe/modifier[Raw event descriptor]
        uprobe/ref_ctr_offset=0..0xffffffff,retprobe/modifier

Committer notes:

Address this build error in various distros:

  55    58.44 ubuntu:24.04                  : FAIL gcc version 13.2.0 (Ubuntu 13.2.0-17ubuntu2)
    util/pmu.c:1638:70: error: '_Static_assert' with no message is a C2x extension [-Werror,-Wc2x-extensions]
     1638 |         _Static_assert(ARRAY_SIZE(terms) == __PARSE_EVENTS__TERM_TYPE_NR - 6);
          |                                                                             ^
          |                                                                             , ""
    1 error generated.

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20240308001915.4060155-5-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Ian Rogers
39aa4ff61f perf pmu: Drop "default_core" from alias names
"default_core" is used by jevents.py for json events' PMU name when
none is specified. On x86 the "default_core" is typically the PMU
"cpu". When creating an alias see if the event's PMU name is
"default_core" in which case don't record it. This means in places
like "perf list" the PMU's name will be used in its place.

Before:

$ perf list --details
  ...
  cache:
    l1d.replacement
         [Counts the number of cache lines replaced in L1 data cache]
          default_core/event=0x51,period=0x186a3,umask=0x1/
  ...

After:

$ perf list --details
  ...
  cache:
    l1d.replacement
         [Counts the number of cache lines replaced in L1 data cache. Unit: cpu]
          cpu/event=0x51,period=0x186a3,umask=0x1/
  ...

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20240308001915.4060155-3-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Ian Rogers
525615ef6d perf list: Add tracepoint encoding to detailed output
The tracepoint id holds the config value and is probed in determining
what an event is. Add reading of the id so that we can display the
event encoding as:

  $ perf list --details
  ...
    alarmtimer:alarmtimer_cancel                       [Tracepoint event]
          tracepoint/config=0x18c/
  ...

Signed-off-by: Ian Rogers <irogers@google.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Kan Liang <kan.liang@linux.intel.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Yang Jihong <yangjihong1@huawei.com>
Link: https://lore.kernel.org/r/20240308001915.4060155-2-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
bd62de0808 perf annotate-data: Do not retry for invalid types
In some cases, it was able to find a type or location info (for per-cpu
variable) but cannot match because of invalid offset or missing global
information.  In those cases, it's meaningless to go to the outer scope
and retry because there will be no additional information.

Let's change the return type of find_matching_type() and bail out if it
returns -1 for the cases.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-24-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
55ee3d005d perf annotate-data: Add a cache for global variable types
They are often searched by many different places.  Let's add a cache
for them to reduce the duplicate DWARF access.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-23-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
b3c95109c1 perf annotate-data: Add stack canary type
When the stack protector is enabled, compiler would generate code to
check stack overflow with a special value called 'stack carary' at
runtime.  On x86_64, GCC hard-codes the stack canary as %gs:40.

While there's a definition of fixed_percpu_data in asm/processor.h,
it seems that the header is not included everywhere and many places
it cannot find the type info.  As it's in the well-known location (at
%gs:40), let's add a pseudo stack canary type to handle it specially.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-22-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
eb9190afae perf annotate-data: Handle ADD instructions
There are different patterns for percpu variable access using a constant
value added to the base.

  2aeb:  mov    -0x7da0f7e0(,%rax,8),%r14  # r14 = __per_cpu_offset[cpu]
  2af3:  mov    $0x34740,%rax              # rax = address of runqueues
* 2afa:  add    %rax,%r14                  # r14 = &per_cpu(runqueues, cpu)
  2bfd:  cmpl   $0x0,0x10(%r14)            # cpu_rq(cpu)->has_blocked_load
  2b03:  je     0x2b36

At the first instruction, r14 has the __per_cpu_offset.  And then rax
has an immediate value and then added to r14 to calculate the address of
a per-cpu variable.  So it needs to track the immediate values and ADD
instructions.

Similar but a little different case is to use "this_cpu_off" instead of
"__per_cpu_offset" for the current CPU.  This time the variable address
comes with PC-rel addressing.

  89:  mov     $0x34740,%rax                # rax = address of runqueues
* 90:  add     %gs:0x7f015f60(%rip),%rax    # 19a78  <this_cpu_off>
  98:  incl    0xd8c(%rax)                  # cpu_rq(cpu)->sched_count

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-21-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
f5b095924d perf annotate-data: Support general per-cpu access
This is to support per-cpu variable access often without a matching
DWARF entry.  For some reason, I cannot find debug info of per-cpu
variables sometimes.  They have more complex pattern to calculate the
address of per-cpu variables like below.

  2b7d:  mov    -0x1e0(%rbp),%rax           ; rax = cpu
  2b84:  mov    -0x7da0f7e0(,%rax,8),%rcx   ; rcx = __per_cpu_offset[cpu]
* 2b8c:  mov    0x34870(%rcx),%rax          ; *(__per_cpu_offset[cpu] + 0x34870)

Let's assume the rax register has a number for a CPU at 2b7d.  The next
instruction is to get the per-cpu offset' for that cpu.  The offset
-0x7da0f7e0 is 0xffffffff825f0820 in u64 which is the address of the
'__per_cpu_offset' array in my system.  So it'd get the actual offset
of that CPU's per-cpu region and save it to the rcx register.

Then, at 2b8c, accesses using rcx can be handled same as the global
variable access.  To handle this case, it should check if the offset
of the instruction matches to the address of '__per_cpu_offset'.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-20-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
ad62edbfc5 perf annotate-data: Track instructions with a this-cpu variable
Like global variables, this per-cpu variables should be tracked
correctly.  Factor our get_global_var_type() to handle both global
and per-cpu (for this cpu) variables in the same manner.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-19-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
02e17ca917 perf annotate-data: Handle this-cpu variables in kernel
On x86, the kernel gets the current task using the current macro like
below:

  #define current  get_current()

  static __always_inline struct task_struct *get_current(void)
  {
      return this_cpu_read_stable(pcpu_hot.current_task);
  }

So it returns the current_task field of struct pcpu_hot which is the
first member.  On my build, it's located at 0x32940.

  $ nm vmlinux | grep pcpu_hot
  0000000000032940 D pcpu_hot

And the current macro generates the instructions like below:

  mov  %gs:0x32940, %rcx

So the %gs segment register points to the beginning of the per-cpu
region of this cpu and it points the variable with a constant.

Let's update the instruction location info to have a segment register
and handle %gs in kernel to look up a global variable.  Pretend it as
a global variable by changing the register number to DWARF_REG_PC.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-18-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
cbaf89a8c5 perf annotate: Parse x86 segment register location
Add a segment field in the struct annotated_insn_loc and save it for the
segment based addressing like %gs:0x28.  For simplicity it now handles
%gs register only.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-17-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00
Namhyung Kim
bdc80ace07 perf annotate-data: Check register state for type
As instruction tracking updates the type state for each register, check
the final type info for the target register at the given instruction.

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>
Link: https://lore.kernel.org/r/20240319055115.4063940-16-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2024-03-21 10:41:29 -03:00