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: 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-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
d001c7a7f4
commit
2b08f219d5
1 changed files with 40 additions and 10 deletions
|
@ -10,20 +10,27 @@
|
|||
#include "util/annotate.h"
|
||||
#include "util/annotate-data.h"
|
||||
#include "util/evsel.h"
|
||||
#include "util/evlist.h"
|
||||
#include "util/sort.h"
|
||||
|
||||
struct annotated_data_browser {
|
||||
struct ui_browser b;
|
||||
struct list_head entries;
|
||||
int nr_events;
|
||||
};
|
||||
|
||||
struct browser_entry {
|
||||
struct list_head node;
|
||||
struct annotated_member *data;
|
||||
struct type_hist_entry hists;
|
||||
struct type_hist_entry *hists;
|
||||
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,
|
||||
struct type_hist_entry *src)
|
||||
{
|
||||
|
@ -33,17 +40,21 @@ static void update_hist_entry(struct type_hist_entry *dst,
|
|||
|
||||
static int get_member_overhead(struct annotated_data_type *adt,
|
||||
struct browser_entry *entry,
|
||||
struct evsel *evsel)
|
||||
struct evsel *leader)
|
||||
{
|
||||
struct annotated_member *member = entry->data;
|
||||
int i;
|
||||
int i, k;
|
||||
|
||||
for (i = 0; i < member->size; i++) {
|
||||
struct type_hist *h;
|
||||
struct evsel *evsel;
|
||||
int offset = member->offset + i;
|
||||
|
||||
h = adt->histograms[evsel->core.idx];
|
||||
update_hist_entry(&entry->hists, &h->addr[offset]);
|
||||
for_each_group_evsel(evsel, leader) {
|
||||
h = adt->histograms[evsel->core.idx];
|
||||
k = evsel__group_idx(evsel);
|
||||
update_hist_entry(&entry->hists[k], &h->addr[offset]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -61,6 +72,12 @@ static int add_child_entries(struct annotated_data_browser *browser,
|
|||
if (entry == NULL)
|
||||
return -1;
|
||||
|
||||
entry->hists = calloc(browser->nr_events, sizeof(*entry->hists));
|
||||
if (entry->hists == NULL) {
|
||||
free(entry);
|
||||
return -1;
|
||||
}
|
||||
|
||||
entry->data = member;
|
||||
entry->indent = indent;
|
||||
if (get_member_overhead(adt, entry, evsel) < 0) {
|
||||
|
@ -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_del_init(&pos->node);
|
||||
free(pos->hists);
|
||||
free(pos);
|
||||
}
|
||||
}
|
||||
|
@ -126,6 +144,7 @@ static int browser__show(struct ui_browser *uib)
|
|||
{
|
||||
struct hist_entry *he = uib->priv;
|
||||
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";
|
||||
char title[256];
|
||||
|
||||
|
@ -146,7 +165,8 @@ static int browser__show(struct ui_browser *uib)
|
|||
else
|
||||
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");
|
||||
ui_browser__write_nstring(uib, "", uib->width);
|
||||
return 0;
|
||||
|
@ -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)
|
||||
{
|
||||
struct annotated_data_browser *browser = get_browser(uib);
|
||||
struct browser_entry *be = entry;
|
||||
struct annotated_member *member = be->data;
|
||||
struct hist_entry *he = uib->priv;
|
||||
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) {
|
||||
bool current = ui_browser__is_current_entry(uib, row);
|
||||
|
||||
/* print the closing bracket */
|
||||
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};",
|
||||
"", "", be->indent * 4, "");
|
||||
ui_browser__write_nstring(uib, "", uib->width);
|
||||
|
@ -194,8 +216,12 @@ static void browser__write(struct ui_browser *uib, void *entry, int row)
|
|||
}
|
||||
|
||||
/* print the number */
|
||||
browser__write_overhead(uib, adt->histograms[evsel->core.idx],
|
||||
&be->hists, row);
|
||||
for_each_group_evsel(evsel, leader) {
|
||||
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 */
|
||||
if (be->indent == 0 && !member->var_name) {
|
||||
|
@ -267,11 +293,15 @@ int hist_entry__annotate_data_tui(struct hist_entry *he, struct evsel *evsel,
|
|||
.priv = he,
|
||||
.extra_title_lines = 1,
|
||||
},
|
||||
.nr_events = 1,
|
||||
};
|
||||
int ret;
|
||||
|
||||
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);
|
||||
if (ret == 0)
|
||||
ret = annotated_data_browser__run(&browser, evsel, hbt);
|
||||
|
|
Loading…
Reference in a new issue