diff options
author | Namhyung Kim <namhyung@kernel.org> | 2024-04-11 06:32:54 +0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2024-04-12 18:02:06 +0300 |
commit | 2b08f219d592d5b3d17db9a3850a9d793e6c9d83 (patch) | |
tree | a89219f050ab6d0886f1a006c460386c2c872b3e | |
parent | d001c7a7f473674353311a79cf140d054b26afcd (diff) | |
download | linux-2b08f219d592d5b3d17db9a3850a9d793e6c9d83.tar.xz |
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>
-rw-r--r-- | tools/perf/ui/browsers/annotate-data.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/tools/perf/ui/browsers/annotate-data.c b/tools/perf/ui/browsers/annotate-data.c index fefacaaf16db..a4a0f042f201 100644 --- a/tools/perf/ui/browsers/annotate-data.c +++ b/tools/perf/ui/browsers/annotate-data.c @@ -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); |