Commit 2b08f219 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf annotate-data: Support event group display in TUI

Like in stdio, it should print all events in a group together.

Committer notes:

Collect it:

  root@number:~# perf record -a -e '{cpu_core/mem-loads,ldlat=30/P,cpu_core/mem-stores/P}'
  ^C[ perf record: Woken up 8 times to write data ]
  [ perf record: Captured and wrote 4.980 MB perf.data (55825 samples) ]
  root@number:~#

Then do it in stdio:

  root@number:~# perf annotate --stdio --data-type

  Annotate type: 'union ' in /usr/lib64/libc.so.6 (1131 samples):
   event[0] = cpu_core/mem-loads,ldlat=30/P
   event[1] = cpu_core/mem-stores/P
  ============================================================================
           Percent     offset       size  field
    100.00  100.00          0         40  union    {
    100.00  100.00          0         40      struct __pthread_mutex_s    __data {
     48.61   23.46          0          4          int     __lock;
      0.00    0.48          4          4          unsigned int    __count;
      6.38   41.32          8          4          int     __owner;
      8.74   34.02         12          4          unsigned int    __nusers;
     35.66    0.26         16          4          int     __kind;
      0.61    0.45         20          2          short int       __spins;
      0.00    0.00         22          2          short int       __elision;
      0.00    0.00         24         16          __pthread_list_t        __list {
      0.00    0.00         24          8              struct __pthread_internal_list*     __prev;
      0.00    0.00         32          8              struct __pthread_internal_list*     __next;
                                                  };
                                              };
      0.00    0.00          0          0      char*       __size;
     48.61   23.94          0          8      long int    __align;
                                          };

Now with TUI before this patch:

  root@number:~# perf annotate --tui --data-type
  Annotate type: 'union ' (790 samples)
      Percent     Offset       Size  Field
       100.00          0         40  union  {
       100.00          0         40      struct __pthread_mutex_s __data {
        48.61          0          4          int  __lock;
         0.00          4          4          unsigned int __count;
         6.38          8          4          int  __owner;
         8.74         12          4          unsigned int __nusers;
        35.66         16          4          int  __kind;
         0.61         20          2          short int    __spins;
         0.00         22          2          short int    __elision;
         0.00         24         16          __pthread_list_t     __list {
         0.00         24          8              struct __pthread_internal_list*  __prev;
         0.00         32          8              struct __pthread_internal_list*  __next;

         0.00          0          0      char*    __size;
        48.61          0          8      long int __align;
                                     };

And now after this patch:

Annotate type: 'union ' (790 samples)
               Percent     Offset       Size  Field
     100.00     100.00          0         40  union  {
     100.00     100.00          0         40      struct __pthread_mutex_s      __data {
      48.61      23.46          0          4          int       __lock;
       0.00       0.48          4          4          unsigned int      __count;
       6.38      41.32          8          4          int       __owner;
       8.74      34.02         12          4          unsigned int      __nusers;
      35.66       0.26         16          4          int       __kind;
       0.61       0.45         20          2          short int __spins;
       0.00       0.00         22          2          short int __elision;
       0.00       0.00         24         16          __pthread_list_t  __list {
       0.00       0.00         24          8              struct __pthread_internal_list*       __prev;
       0.00       0.00         32          8              struct __pthread_internal_list*       __next;
                                                      };
                                                  };
       0.00       0.00          0          0      char* __size;
      48.61      23.94          0          8      long int      __align;
                                              };

On a followup patch the --tui output should have this that is present in
--stdio:

  And the --stdio has all the missing info in TUI:

    Annotate type: 'union ' in /usr/lib64/libc.so.6 (1131 samples):
     event[0] = cpu_core/mem-loads,ldlat=30/P
     event[1] = cpu_core/mem-stores/P
Reviewed-by: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Tested-by: default avatarArnaldo 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-6-namhyung@kernel.orgSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent d001c7a7
...@@ -10,20 +10,27 @@ ...@@ -10,20 +10,27 @@
#include "util/annotate.h" #include "util/annotate.h"
#include "util/annotate-data.h" #include "util/annotate-data.h"
#include "util/evsel.h" #include "util/evsel.h"
#include "util/evlist.h"
#include "util/sort.h" #include "util/sort.h"
struct annotated_data_browser { struct annotated_data_browser {
struct ui_browser b; struct ui_browser b;
struct list_head entries; struct list_head entries;
int nr_events;
}; };
struct browser_entry { struct browser_entry {
struct list_head node; struct list_head node;
struct annotated_member *data; struct annotated_member *data;
struct type_hist_entry hists; struct type_hist_entry *hists;
int indent; int indent;
}; };
static struct annotated_data_browser *get_browser(struct ui_browser *uib)
{
return container_of(uib, struct annotated_data_browser, b);
}
static void update_hist_entry(struct type_hist_entry *dst, static void update_hist_entry(struct type_hist_entry *dst,
struct type_hist_entry *src) struct type_hist_entry *src)
{ {
...@@ -33,17 +40,21 @@ static void update_hist_entry(struct type_hist_entry *dst, ...@@ -33,17 +40,21 @@ static void update_hist_entry(struct type_hist_entry *dst,
static int get_member_overhead(struct annotated_data_type *adt, static int get_member_overhead(struct annotated_data_type *adt,
struct browser_entry *entry, struct browser_entry *entry,
struct evsel *evsel) struct evsel *leader)
{ {
struct annotated_member *member = entry->data; struct annotated_member *member = entry->data;
int i; int i, k;
for (i = 0; i < member->size; i++) { for (i = 0; i < member->size; i++) {
struct type_hist *h; struct type_hist *h;
struct evsel *evsel;
int offset = member->offset + i; int offset = member->offset + i;
h = adt->histograms[evsel->core.idx]; for_each_group_evsel(evsel, leader) {
update_hist_entry(&entry->hists, &h->addr[offset]); h = adt->histograms[evsel->core.idx];
k = evsel__group_idx(evsel);
update_hist_entry(&entry->hists[k], &h->addr[offset]);
}
} }
return 0; return 0;
} }
...@@ -61,6 +72,12 @@ static int add_child_entries(struct annotated_data_browser *browser, ...@@ -61,6 +72,12 @@ static int add_child_entries(struct annotated_data_browser *browser,
if (entry == NULL) if (entry == NULL)
return -1; return -1;
entry->hists = calloc(browser->nr_events, sizeof(*entry->hists));
if (entry->hists == NULL) {
free(entry);
return -1;
}
entry->data = member; entry->data = member;
entry->indent = indent; entry->indent = indent;
if (get_member_overhead(adt, entry, evsel) < 0) { if (get_member_overhead(adt, entry, evsel) < 0) {
...@@ -113,6 +130,7 @@ static void annotated_data_browser__delete_entries(struct annotated_data_browser ...@@ -113,6 +130,7 @@ static void annotated_data_browser__delete_entries(struct annotated_data_browser
list_for_each_entry_safe(pos, tmp, &browser->entries, node) { list_for_each_entry_safe(pos, tmp, &browser->entries, node) {
list_del_init(&pos->node); list_del_init(&pos->node);
free(pos->hists);
free(pos); free(pos);
} }
} }
...@@ -126,6 +144,7 @@ static int browser__show(struct ui_browser *uib) ...@@ -126,6 +144,7 @@ static int browser__show(struct ui_browser *uib)
{ {
struct hist_entry *he = uib->priv; struct hist_entry *he = uib->priv;
struct annotated_data_type *adt = he->mem_type; struct annotated_data_type *adt = he->mem_type;
struct annotated_data_browser *browser = get_browser(uib);
const char *help = "Press 'h' for help on key bindings"; const char *help = "Press 'h' for help on key bindings";
char title[256]; char title[256];
...@@ -146,7 +165,8 @@ static int browser__show(struct ui_browser *uib) ...@@ -146,7 +165,8 @@ static int browser__show(struct ui_browser *uib)
else else
strcpy(title, "Percent"); strcpy(title, "Percent");
ui_browser__printf(uib, " %10s %10s %10s %s", ui_browser__printf(uib, "%*s %10s %10s %10s %s",
11 * (browser->nr_events - 1), "",
title, "Offset", "Size", "Field"); title, "Offset", "Size", "Field");
ui_browser__write_nstring(uib, "", uib->width); ui_browser__write_nstring(uib, "", uib->width);
return 0; return 0;
...@@ -175,18 +195,20 @@ static void browser__write_overhead(struct ui_browser *uib, ...@@ -175,18 +195,20 @@ static void browser__write_overhead(struct ui_browser *uib,
static void browser__write(struct ui_browser *uib, void *entry, int row) static void browser__write(struct ui_browser *uib, void *entry, int row)
{ {
struct annotated_data_browser *browser = get_browser(uib);
struct browser_entry *be = entry; struct browser_entry *be = entry;
struct annotated_member *member = be->data; struct annotated_member *member = be->data;
struct hist_entry *he = uib->priv; struct hist_entry *he = uib->priv;
struct annotated_data_type *adt = he->mem_type; struct annotated_data_type *adt = he->mem_type;
struct evsel *evsel = hists_to_evsel(he->hists); struct evsel *leader = hists_to_evsel(he->hists);
struct evsel *evsel;
if (member == NULL) { if (member == NULL) {
bool current = ui_browser__is_current_entry(uib, row); bool current = ui_browser__is_current_entry(uib, row);
/* print the closing bracket */ /* print the closing bracket */
ui_browser__set_percent_color(uib, 0, current); ui_browser__set_percent_color(uib, 0, current);
ui_browser__write_nstring(uib, "", 11); ui_browser__write_nstring(uib, "", 11 * browser->nr_events);
ui_browser__printf(uib, " %10s %10s %*s};", ui_browser__printf(uib, " %10s %10s %*s};",
"", "", be->indent * 4, ""); "", "", be->indent * 4, "");
ui_browser__write_nstring(uib, "", uib->width); ui_browser__write_nstring(uib, "", uib->width);
...@@ -194,8 +216,12 @@ static void browser__write(struct ui_browser *uib, void *entry, int row) ...@@ -194,8 +216,12 @@ static void browser__write(struct ui_browser *uib, void *entry, int row)
} }
/* print the number */ /* print the number */
browser__write_overhead(uib, adt->histograms[evsel->core.idx], for_each_group_evsel(evsel, leader) {
&be->hists, row); struct type_hist *h = adt->histograms[evsel->core.idx];
int idx = evsel__group_idx(evsel);
browser__write_overhead(uib, h, &be->hists[idx], row);
}
/* print type info */ /* print type info */
if (be->indent == 0 && !member->var_name) { if (be->indent == 0 && !member->var_name) {
...@@ -267,11 +293,15 @@ int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel, ...@@ -267,11 +293,15 @@ int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,
.priv = he, .priv = he,
.extra_title_lines = 1, .extra_title_lines = 1,
}, },
.nr_events = 1,
}; };
int ret; int ret;
ui_helpline__push("Press ESC to exit"); ui_helpline__push("Press ESC to exit");
if (evsel__is_group_event(evsel))
browser.nr_events = evsel->core.nr_members;
ret = annotated_data_browser__collect_entries(&browser); ret = annotated_data_browser__collect_entries(&browser);
if (ret == 0) if (ret == 0)
ret = annotated_data_browser__run(&browser, evsel, hbt); ret = annotated_data_browser__run(&browser, evsel, hbt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment