]> git.itanic.dy.fi Git - linux-stable/commitdiff
perf report: Add 'type' sort key
authorNamhyung Kim <namhyung@kernel.org>
Wed, 13 Dec 2023 00:13:14 +0000 (16:13 -0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Sun, 24 Dec 2023 01:39:42 +0000 (22:39 -0300)
The 'type' sort key is to aggregate hist entries by data type they
access.  Add mem_type field to hist_entry struct to save the type.  If
hist_entry__get_data_type() returns NULL, it'd use the 'unknown_type'
instance.

Committer testing:

Before:

  # perf mem record  sleep 2s
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.037 MB perf.data (4 samples) ]
  root@number:/home/acme/Downloads# perf report --stdio -s type
  Error:
  Unknown --sort key: `type'
   Usage: perf report [<options>]

      -s, --sort <key[,key2...]>
                            sort by key(s): overhead overhead_sys overhead_us overhead_guest_sys
                            overhead_guest_us overhead_children sample period
                            pid comm dso symbol parent cpu socket srcline srcfile
                            local_weight weight transaction trace symbol_size
                            dso_size cgroup cgroup_id ipc_null time code_page_size
                            local_ins_lat ins_lat local_p_stage_cyc p_stage_cyc
                            addr local_retire_lat retire_lat simd dso_from dso_to
                            symbol_from symbol_to mispredict abort in_tx cycles
                            srcline_from srcline_to ipc_lbr addr_from addr_to
                            symbol_daddr dso_daddr locked tlb mem snoop dcacheline
                            symbol_iaddr phys_daddr data_page_size blocked
  #

After:

  # perf report --stdio -s type
  # 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
  # ........  .........
  #
     100.00%  (unknown)

  #
  # (Tip: Print event counts in CSV format with: perf stat -x,)
  #
  # rpm -q kernel-debuginfo
  kernel-debuginfo-6.6.4-200.fc39.x86_64
  # uname -r
  6.6.4-200.fc39.x86_64
  #

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-9-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/Documentation/perf-report.txt
tools/perf/util/annotate-data.h
tools/perf/util/hist.h
tools/perf/util/sort.c
tools/perf/util/sort.h

index af068b4f1e5a696464ba2040b7b39a4831b32050..aec34417090b0cfd6df90b8b1a94dea842fdabd9 100644 (file)
@@ -118,6 +118,7 @@ OPTIONS
        - retire_lat: On X86, this reports pipeline stall of this instruction compared
          to the previous instruction in cycles. And currently supported only on X86
        - simd: Flags describing a SIMD operation. "e" for empty Arm SVE predicate. "p" for partial Arm SVE predicate
+       - type: Data type of sample memory access.
 
        By default, comm, dso and symbol keys are used.
        (i.e. --sort comm,dso,symbol)
index ab9f187bd7f13f2c69ca84abf1517690e6c081f8..6efdd7e21b286bf758380294c992929393be3712 100644 (file)
@@ -22,6 +22,8 @@ struct annotated_data_type {
        int type_size;
 };
 
+extern struct annotated_data_type unknown_type;
+
 #ifdef HAVE_DWARF_SUPPORT
 
 /* Returns data type at the location (ip, reg, offset) */
index 5d0db96609dff50bd16f44f1061323de4c1e7d5c..7ebbf427b1eacda664038ee851e5aaec38d25c80 100644 (file)
@@ -82,6 +82,7 @@ enum hist_column {
        HISTC_ADDR_TO,
        HISTC_ADDR,
        HISTC_SIMD,
+       HISTC_TYPE,
        HISTC_NR_COLS, /* Last entry */
 };
 
index 27b123ccd2d15e763962e6f05c2861c304780be3..e647f0117bb568537f1156f41e8abbc094fbf02e 100644 (file)
@@ -24,6 +24,7 @@
 #include "strbuf.h"
 #include "mem-events.h"
 #include "annotate.h"
+#include "annotate-data.h"
 #include "event.h"
 #include "time-utils.h"
 #include "cgroup.h"
@@ -2094,7 +2095,7 @@ struct sort_entry sort_dso_size = {
        .se_width_idx   = HISTC_DSO_SIZE,
 };
 
-/* --sort dso_size */
+/* --sort addr */
 
 static int64_t
 sort__addr_cmp(struct hist_entry *left, struct hist_entry *right)
@@ -2131,6 +2132,69 @@ struct sort_entry sort_addr = {
        .se_width_idx   = HISTC_ADDR,
 };
 
+/* --sort type */
+
+struct annotated_data_type unknown_type = {
+       .type_name = (char *)"(unknown)",
+};
+
+static int64_t
+sort__type_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+       return sort__addr_cmp(left, right);
+}
+
+static void sort__type_init(struct hist_entry *he)
+{
+       if (he->mem_type)
+               return;
+
+       he->mem_type = hist_entry__get_data_type(he);
+       if (he->mem_type == NULL)
+               he->mem_type = &unknown_type;
+}
+
+static int64_t
+sort__type_collapse(struct hist_entry *left, struct hist_entry *right)
+{
+       struct annotated_data_type *left_type = left->mem_type;
+       struct annotated_data_type *right_type = right->mem_type;
+
+       if (!left_type) {
+               sort__type_init(left);
+               left_type = left->mem_type;
+       }
+
+       if (!right_type) {
+               sort__type_init(right);
+               right_type = right->mem_type;
+       }
+
+       return strcmp(left_type->type_name, right_type->type_name);
+}
+
+static int64_t
+sort__type_sort(struct hist_entry *left, struct hist_entry *right)
+{
+       return sort__type_collapse(left, right);
+}
+
+static int hist_entry__type_snprintf(struct hist_entry *he, char *bf,
+                                    size_t size, unsigned int width)
+{
+       return repsep_snprintf(bf, size, "%-*s", width, he->mem_type->type_name);
+}
+
+struct sort_entry sort_type = {
+       .se_header      = "Data Type",
+       .se_cmp         = sort__type_cmp,
+       .se_collapse    = sort__type_collapse,
+       .se_sort        = sort__type_sort,
+       .se_init        = sort__type_init,
+       .se_snprintf    = hist_entry__type_snprintf,
+       .se_width_idx   = HISTC_TYPE,
+};
+
 
 struct sort_dimension {
        const char              *name;
@@ -2185,7 +2249,8 @@ static struct sort_dimension common_sort_dimensions[] = {
        DIM(SORT_ADDR, "addr", sort_addr),
        DIM(SORT_LOCAL_RETIRE_LAT, "local_retire_lat", sort_local_p_stage_cyc),
        DIM(SORT_GLOBAL_RETIRE_LAT, "retire_lat", sort_global_p_stage_cyc),
-       DIM(SORT_SIMD, "simd", sort_simd)
+       DIM(SORT_SIMD, "simd", sort_simd),
+       DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type),
 };
 
 #undef DIM
index ecfb7f1359d5ee8a16ad02dabf226d467e2937d6..aabf0b8331a359d2e56db2cbf2741e8e033185de 100644 (file)
@@ -15,6 +15,7 @@
 
 struct option;
 struct thread;
+struct annotated_data_type;
 
 extern regex_t parent_regex;
 extern const char *sort_order;
@@ -34,6 +35,7 @@ extern struct sort_entry sort_dso_to;
 extern struct sort_entry sort_sym_from;
 extern struct sort_entry sort_sym_to;
 extern struct sort_entry sort_srcline;
+extern struct sort_entry sort_type;
 extern const char default_mem_sort_order[];
 extern bool chk_double_cl;
 
@@ -154,6 +156,7 @@ struct hist_entry {
        struct perf_hpp_list    *hpp_list;
        struct hist_entry       *parent_he;
        struct hist_entry_ops   *ops;
+       struct annotated_data_type *mem_type;
        union {
                /* this is for hierarchical entry structure */
                struct {
@@ -243,6 +246,7 @@ enum sort_type {
        SORT_LOCAL_RETIRE_LAT,
        SORT_GLOBAL_RETIRE_LAT,
        SORT_SIMD,
+       SORT_ANNOTATE_DATA_TYPE,
 
        /* branch stack specific sort keys */
        __SORT_BRANCH_STACK,