Skip to content

Commit 227ad32

Browse files
namhyungacmel
authored andcommitted
perf annotate: Support event group display
When events are grouped together, it'd be natural to show them at once like in other mode. Handle group leaders with members to collect the number of samples together and display like below: $ perf annotate --data-type --group ... Annotate type: 'struct page' in vmlinux (1 samples): event[0] = cpu/mem-loads,ldlat=30/P event[1] = cpu/mem-stores/P event[2] = dummy:u ============================================================================ samples offset size field 1 0 0 0 64 struct page { 0 0 0 0 8 long unsigned int flags; 0 0 0 8 40 union { 0 0 0 8 40 struct { 0 0 0 8 16 union { 0 0 0 8 16 struct list_head lru { 0 0 0 8 8 struct list_head* next; 0 0 0 16 8 struct list_head* prev; }; 0 0 0 8 16 struct { 0 0 0 8 8 void* __filler; 0 0 0 16 4 unsigned int mlock_count; }; 0 0 0 8 16 struct list_head buddy_list { 0 0 0 8 8 struct list_head* next; 0 0 0 16 8 struct list_head* prev; }; Signed-off-by: Namhyung Kim <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Masami Hiramatsu <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: [email protected] Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 263925b commit 227ad32

File tree

1 file changed

+77
-12
lines changed

1 file changed

+77
-12
lines changed

tools/perf/builtin-annotate.c

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -325,19 +325,64 @@ static int hist_entry__tty_annotate(struct hist_entry *he,
325325
return symbol__tty_annotate2(&he->ms, evsel);
326326
}
327327

328+
static void print_annotated_data_header(struct hist_entry *he, struct evsel *evsel)
329+
{
330+
struct dso *dso = map__dso(he->ms.map);
331+
int nr_members = 1;
332+
int nr_samples = he->stat.nr_events;
333+
334+
if (evsel__is_group_event(evsel)) {
335+
struct hist_entry *pair;
336+
337+
list_for_each_entry(pair, &he->pairs.head, pairs.node)
338+
nr_samples += pair->stat.nr_events;
339+
}
340+
341+
printf("Annotate type: '%s' in %s (%d samples):\n",
342+
he->mem_type->self.type_name, dso->name, nr_samples);
343+
344+
if (evsel__is_group_event(evsel)) {
345+
struct evsel *pos;
346+
int i = 0;
347+
348+
for_each_group_evsel(pos, evsel)
349+
printf(" event[%d] = %s\n", i++, pos->name);
350+
351+
nr_members = evsel->core.nr_members;
352+
}
353+
354+
printf("============================================================================\n");
355+
printf("%*s %10s %10s %s\n", 11 * nr_members, "samples", "offset", "size", "field");
356+
}
357+
328358
static void print_annotated_data_type(struct annotated_data_type *mem_type,
329359
struct annotated_member *member,
330360
struct evsel *evsel, int indent)
331361
{
332362
struct annotated_member *child;
333363
struct type_hist *h = mem_type->histograms[evsel->core.idx];
334-
int i, samples = 0;
364+
int i, nr_events = 1, samples = 0;
335365

336366
for (i = 0; i < member->size; i++)
337367
samples += h->addr[member->offset + i].nr_samples;
368+
printf(" %10d", samples);
369+
370+
if (evsel__is_group_event(evsel)) {
371+
struct evsel *pos;
372+
373+
for_each_group_member(pos, evsel) {
374+
h = mem_type->histograms[pos->core.idx];
375+
376+
samples = 0;
377+
for (i = 0; i < member->size; i++)
378+
samples += h->addr[member->offset + i].nr_samples;
379+
printf(" %10d", samples);
380+
}
381+
nr_events = evsel->core.nr_members;
382+
}
338383

339-
printf(" %10d %10d %10d %*s%s\t%s",
340-
samples, member->offset, member->size, indent, "", member->type_name,
384+
printf(" %10d %10d %*s%s\t%s",
385+
member->offset, member->size, indent, "", member->type_name,
341386
member->var_name ?: "");
342387

343388
if (!list_empty(&member->children))
@@ -347,7 +392,7 @@ static void print_annotated_data_type(struct annotated_data_type *mem_type,
347392
print_annotated_data_type(mem_type, child, evsel, indent + 4);
348393

349394
if (!list_empty(&member->children))
350-
printf("%*s}", 35 + indent, "");
395+
printf("%*s}", 11 * nr_events + 24 + indent, "");
351396
printf(";\n");
352397
}
353398

@@ -391,8 +436,6 @@ static void hists__find_annotations(struct hists *hists,
391436
}
392437

393438
if (ann->data_type) {
394-
struct dso *dso = map__dso(he->ms.map);
395-
396439
/* skip unknown type */
397440
if (he->mem_type->histograms == NULL)
398441
goto find_next;
@@ -414,11 +457,7 @@ static void hists__find_annotations(struct hists *hists,
414457
goto find_next;
415458
}
416459

417-
printf("Annotate type: '%s' in %s (%d samples):\n",
418-
he->mem_type->self.type_name, dso->name, he->stat.nr_events);
419-
printf("============================================================================\n");
420-
printf(" %10s %10s %10s %s\n", "samples", "offset", "size", "field");
421-
460+
print_annotated_data_header(he, evsel);
422461
print_annotated_data_type(he->mem_type, &he->mem_type->self, evsel, 0);
423462
printf("\n");
424463
goto find_next;
@@ -521,8 +560,20 @@ static int __cmd_annotate(struct perf_annotate *ann)
521560
evsel__reset_sample_bit(pos, CALLCHAIN);
522561
evsel__output_resort(pos, NULL);
523562

524-
if (symbol_conf.event_group && !evsel__is_group_leader(pos))
563+
/*
564+
* An event group needs to display other events too.
565+
* Let's delay printing until other events are processed.
566+
*/
567+
if (symbol_conf.event_group) {
568+
if (!evsel__is_group_leader(pos)) {
569+
struct hists *leader_hists;
570+
571+
leader_hists = evsel__hists(evsel__leader(pos));
572+
hists__match(leader_hists, hists);
573+
hists__link(leader_hists, hists);
574+
}
525575
continue;
576+
}
526577

527578
hists__find_annotations(hists, pos, ann);
528579
}
@@ -533,6 +584,20 @@ static int __cmd_annotate(struct perf_annotate *ann)
533584
goto out;
534585
}
535586

587+
/* Display group events together */
588+
evlist__for_each_entry(session->evlist, pos) {
589+
struct hists *hists = evsel__hists(pos);
590+
u32 nr_samples = hists->stats.nr_samples;
591+
592+
if (nr_samples == 0)
593+
continue;
594+
595+
if (!symbol_conf.event_group || !evsel__is_group_leader(pos))
596+
continue;
597+
598+
hists__find_annotations(hists, pos, ann);
599+
}
600+
536601
if (use_browser == 2) {
537602
void (*show_annotations)(void);
538603

0 commit comments

Comments
 (0)