Em Wed, Oct 11, 2023 at 08:50:38PM -0700, Namhyung Kim escreveu:
> 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.
Needed the patch below, doing the same that is a bit before for
libtraceevent
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index c79564c1d5df5db3..3fae226d115ef8e6 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2132,6 +2132,7 @@ struct sort_entry sort_addr = {
.se_width_idx = HISTC_ADDR,
};
+#ifdef HAVE_DWARF_SUPPORT
/* --sort type */
static int64_t
@@ -2190,7 +2191,7 @@ struct sort_entry sort_type = {
.se_snprintf = hist_entry__type_snprintf,
.se_width_idx = HISTC_TYPE,
};
-
+#endif // HAVE_DWARF_SUPPORT
struct sort_dimension {
const char *name;
@@ -2246,7 +2247,9 @@ static struct sort_dimension common_sort_dimensions[] = {
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),
+#ifdef HAVE_DWARF_SUPPORT
DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type),
+#endif
};
#undef DIM
On Mon, Oct 23, 2023 at 9:53 AM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> Em Wed, Oct 11, 2023 at 08:50:38PM -0700, Namhyung Kim escreveu:
> > 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.
>
> Needed the patch below, doing the same that is a bit before for
> libtraceevent
I think it can always return unknown_type if libtraceevent is not
enabled. Maybe I need to move the definition here then.
Thanks,
Namhyung
>
> diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
> index c79564c1d5df5db3..3fae226d115ef8e6 100644
> --- a/tools/perf/util/sort.c
> +++ b/tools/perf/util/sort.c
> @@ -2132,6 +2132,7 @@ struct sort_entry sort_addr = {
> .se_width_idx = HISTC_ADDR,
> };
>
> +#ifdef HAVE_DWARF_SUPPORT
> /* --sort type */
>
> static int64_t
> @@ -2190,7 +2191,7 @@ struct sort_entry sort_type = {
> .se_snprintf = hist_entry__type_snprintf,
> .se_width_idx = HISTC_TYPE,
> };
> -
> +#endif // HAVE_DWARF_SUPPORT
>
> struct sort_dimension {
> const char *name;
> @@ -2246,7 +2247,9 @@ static struct sort_dimension common_sort_dimensions[] = {
> 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),
> +#ifdef HAVE_DWARF_SUPPORT
> DIM(SORT_ANNOTATE_DATA_TYPE, "type", sort_type),
> +#endif
> };
>
> #undef DIM
@@ -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)
@@ -17,6 +17,11 @@
#include "strbuf.h"
#include "symbol.h"
+/* Pseudo data types */
+struct annotated_data_type unknown_type = {
+ .type_name = (char *)"(unknown)",
+};
+
/*
* Compare type name and size to maintain them in a tree.
* I'm not sure if DWARF would have information of a single type in many
@@ -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) */
@@ -82,6 +82,7 @@ enum hist_column {
HISTC_ADDR_TO,
HISTC_ADDR,
HISTC_SIMD,
+ HISTC_TYPE,
HISTC_NR_COLS, /* Last entry */
};
@@ -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,65 @@ struct sort_entry sort_addr = {
.se_width_idx = HISTC_ADDR,
};
+/* --sort type */
+
+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 +2245,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
@@ -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,