* [PATCHSET 00/13] perf annotate: Add support for event group view (v1)
@ 2012-11-09 17:27 Namhyung Kim
2012-11-09 17:27 ` [PATCH 01/13] perf annotate: Parse --asm-raw output properly Namhyung Kim
` (12 more replies)
0 siblings, 13 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML
Hi,
This is a patchset to support event grouping on perf annotate.
It depends on perf report event group view patchset [1] and contains
a couple of annotate fixup/cleanup patches that I sent yesterday
(although I fixed a compile problem and added a cleanup patch).
The symbol histograms already contain hit counts for every event so it
was relatively easier to support than that of perf report case. I added
a sort of flexible array to struct source_line and browser_disasm_line
for gathering percent values for each group members.
Patch 0001-0004 are cleanups and can be merged separately. I sent
similar patches yesterday, and this is the up-to-date version.
Patch 0005-0006 are preparation for later patches and
Patch 0007 added event group view for --stdio.
Patch 0008-0009 added event group view for --print-line and
Patch 0010-0012 added event group view for --tui.
Patch 0013 added --group option to enable group view suport.
Let me show you an example:
$ perf annotate --group --stdio --print-line
Sorted summary for file /lib/ld-2.11.1.so
----------------------------------------------
33.33 0.00 /build/buildd/eglibc-2.11.1/elf/rtld.c:381
33.33 0.00 /build/buildd/eglibc-2.11.1/elf/dynamic-link.h:128
33.33 0.00 /build/buildd/eglibc-2.11.1/elf/do-rel.h:105
0.00 75.00 /build/buildd/eglibc-2.11.1/elf/dynamic-link.h:137
0.00 25.00 /build/buildd/eglibc-2.11.1/elf/dynamic-link.h:187
Percent | Source code & Disassembly of ld-2.11.1.so
------------------------------------------------------------------
:
:
:
: Disassembly of section .text:
:
: 0000000000001120 <_dl_rtld_di_serinfo-0x7a20>:
0.00 0.00 : 1120: push %rbp
0.00 0.00 : 1121: mov %rsp,%rbp
0.00 0.00 : 1124: push %r15
0.00 0.00 : 1126: push %r14
0.00 0.00 : 1128: push %r13
0.00 0.00 : 112a: push %r12
0.00 0.00 : 112c: push %rbx
0.00 0.00 : 112d: mov %rdi,%rbx
0.00 0.00 : 1130: sub $0x28,%rsp
0.00 0.00 : 1134: rdtsc
0.00 0.00 : 1136: shl $0x20,%rdx
0.00 0.00 : 113a: mov %eax,%eax
0.00 0.00 : 113c: or %rax,%rdx
0.00 0.00 : 113f: lea -0x26(%rip),%r13 # 1120 <free@plt+0x648>
0.00 0.00 : 1146: sub 0x21ea93(%rip),%r13 # 21fbe0 <calloc+0x208c80>
/build/buildd/eglibc-2.11.1/elf/rtld.c:381
33.33 0.00 : 114d: mov %rdx,0x21ec54(%rip) # 21fda8 <_rtld_global_ro+0x1a8>
0.00 0.00 : 1154: mov %r13,%rdx
...
You can access it via my tree as well.
git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git perf/annotate-group-v1
As always, any comments are welcome, thanks.
Namhyung
[1] http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg337706.html
Namhyung Kim (13):
perf annotate: Parse --asm-raw output properly
perf annotate: Whitespace fixups
perf annotate: Merge same lines in summary view
perf annotate: Don't try to follow jump target on PLT symbols
perf annotate: Pass evsel instead of evidx on annotation functions
perf annotate: Factor out disasm__calc_percent()
perf annotate: Basic support for event group view
perf annotate: Factor out struct source_line_percent
perf annotate: Support event group view for --print-line
perf annotate browser: Make browser_disasm_line->percent an array
perf annotate browser: Use disasm__calc_percent()
perf annotate browser: Support event group view on TUI
perf annotate: Add --group option
tools/perf/builtin-annotate.c | 20 ++-
tools/perf/builtin-top.c | 2 +-
tools/perf/ui/browsers/annotate.c | 151 ++++++++++------
tools/perf/ui/browsers/hists.c | 2 +-
tools/perf/util/annotate.c | 349 ++++++++++++++++++++++++++++++-------
tools/perf/util/annotate.h | 28 ++-
tools/perf/util/hist.h | 5 +-
7 files changed, 418 insertions(+), 139 deletions(-)
--
1.7.9.2
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/13] perf annotate: Parse --asm-raw output properly
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 02/13] perf annotate: Whitespace fixups Namhyung Kim
` (11 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
If --asm-raw option was given, objdump output will contain hex numbers
of the instruction before the symbolic name. However current parser
code doesn't handle it properly. Fix it.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/ui/browsers/annotate.c | 2 ++
tools/perf/util/annotate.c | 36 ++++++++++++++++++++++++++++++++++--
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 3eff17f703f3..aec11f34d394 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -117,6 +117,8 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
ab->addr_width, " ");
slsmg_write_nstring(bf, printed);
slsmg_write_nstring(dl->line, width - printed - 6);
+ } else if (!dl->name) {
+ slsmg_write_nstring(" ", width - 7);
} else {
u64 addr = dl->offset;
int color = -1;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index b14d4df9f149..0565558b6184 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -162,7 +162,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
static int lock__parse(struct ins_operands *ops)
{
- char *name;
+ char *name = NULL;
ops->locked.ops = zalloc(sizeof(*ops->locked.ops));
if (ops->locked.ops == NULL)
@@ -171,7 +171,10 @@ static int lock__parse(struct ins_operands *ops)
if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0)
goto out_free_ops;
- ops->locked.ins = ins__find(name);
+ if (name == NULL)
+ goto out_free_ops;
+
+ ops->locked.ins = ins__find(name);
if (ops->locked.ins == NULL)
goto out_free_ops;
@@ -492,6 +495,9 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
static void disasm_line__init_ins(struct disasm_line *dl)
{
+ if (dl->name == NULL)
+ return;
+
dl->ins = ins__find(dl->name);
if (dl->ins == NULL)
@@ -514,6 +520,32 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
if (name[0] == '\0')
return -1;
+ if (symbol_conf.annotate_asm_raw) {
+ /*
+ * If --asm-raw option was given, objdump output will contain
+ * hex numbers of the instructions before the symbolic name.
+ * They are separated by at least two space characters:
+ *
+ * 400540: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
+ * 400547: 00
+ *
+ * It sometimes was broken to multiple lines due to a limited
+ * width. In this case following condition will be met:
+ *
+ * dl->offset != -1 && dl->name == NULL.
+ */
+ name = strstr(name, " ");
+ if (name == NULL)
+ return 0;
+
+ while (isspace(name[0]))
+ ++name;
+
+ if (name[0] == '\0')
+ return -1;
+
+ }
+
*rawp = name + 1;
while ((*rawp)[0] != '\0' && !isspace((*rawp)[0]))
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/13] perf annotate: Whitespace fixups
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
2012-11-09 17:27 ` [PATCH 01/13] perf annotate: Parse --asm-raw output properly Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-14 7:42 ` [tip:perf/core] " tip-bot for Namhyung Kim
2012-11-09 17:27 ` [PATCH 03/13] perf annotate: Merge same lines in summary view Namhyung Kim
` (10 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML
Some lines are indented by whitespace characters rather than tabs.
Fix them.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/util/annotate.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 0565558b6184..12287b121669 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -175,14 +175,14 @@ static int lock__parse(struct ins_operands *ops)
goto out_free_ops;
ops->locked.ins = ins__find(name);
- if (ops->locked.ins == NULL)
- goto out_free_ops;
+ if (ops->locked.ins == NULL)
+ goto out_free_ops;
- if (!ops->locked.ins->ops)
- return 0;
+ if (!ops->locked.ins->ops)
+ return 0;
- if (ops->locked.ins->ops->parse)
- ops->locked.ins->ops->parse(ops->locked.ops);
+ if (ops->locked.ins->ops->parse)
+ ops->locked.ins->ops->parse(ops->locked.ops);
return 0;
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/13] perf annotate: Merge same lines in summary view
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
2012-11-09 17:27 ` [PATCH 01/13] perf annotate: Parse --asm-raw output properly Namhyung Kim
2012-11-09 17:27 ` [PATCH 02/13] perf annotate: Whitespace fixups Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 04/13] perf annotate: Don't try to follow jump target on PLT symbols Namhyung Kim
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
The --print-line option of perf annotate command shows summary for
each source line. But it didn't merge same lines so that it can
appear multiple times.
* before:
Sorted summary for file /home/namhyung/bin/mcol
----------------------------------------------
21.71 /home/namhyung/tmp/mcol.c:26
20.66 /home/namhyung/tmp/mcol.c:25
9.53 /home/namhyung/tmp/mcol.c:24
7.68 /home/namhyung/tmp/mcol.c:25
7.67 /home/namhyung/tmp/mcol.c:25
7.66 /home/namhyung/tmp/mcol.c:26
7.49 /home/namhyung/tmp/mcol.c:26
6.92 /home/namhyung/tmp/mcol.c:25
6.81 /home/namhyung/tmp/mcol.c:25
1.07 /home/namhyung/tmp/mcol.c:26
0.52 /home/namhyung/tmp/mcol.c:25
0.51 /home/namhyung/tmp/mcol.c:25
0.51 /home/namhyung/tmp/mcol.c:24
* after:
Sorted summary for file /home/namhyung/bin/mcol
----------------------------------------------
50.77 /home/namhyung/tmp/mcol.c:25
37.94 /home/namhyung/tmp/mcol.c:26
10.04 /home/namhyung/tmp/mcol.c:24
To do that, introduce percent_sum field so that the normal
line-by-line output doesn't get changed.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/util/annotate.c | 55 +++++++++++++++++++++++++++++++++++++++++---
tools/perf/util/annotate.h | 1 +
2 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 12287b121669..0ac9cc4c5e7d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -890,12 +890,41 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
struct source_line *iter;
struct rb_node **p = &root->rb_node;
struct rb_node *parent = NULL;
+ int ret;
while (*p != NULL) {
parent = *p;
iter = rb_entry(parent, struct source_line, node);
- if (src_line->percent > iter->percent)
+ ret = strcmp(iter->path, src_line->path);
+ if (ret == 0) {
+ iter->percent_sum += src_line->percent;
+ return;
+ }
+
+ if (ret < 0)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ src_line->percent_sum = src_line->percent;
+
+ rb_link_node(&src_line->node, parent, p);
+ rb_insert_color(&src_line->node, root);
+}
+
+static void __resort_source_line(struct rb_root *root, struct source_line *src_line)
+{
+ struct source_line *iter;
+ struct rb_node **p = &root->rb_node;
+ struct rb_node *parent = NULL;
+
+ while (*p != NULL) {
+ parent = *p;
+ iter = rb_entry(parent, struct source_line, node);
+
+ if (src_line->percent_sum > iter->percent_sum)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -905,6 +934,24 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
rb_insert_color(&src_line->node, root);
}
+static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root)
+{
+ struct source_line *src_line;
+ struct rb_node *node;
+
+ node = rb_first(src_root);
+ while (node) {
+ struct rb_node *next;
+
+ src_line = rb_entry(node, struct source_line, node);
+ next = rb_next(node);
+ rb_erase(node, src_root);
+
+ __resort_source_line(dest_root, src_line);
+ node = next;
+ }
+}
+
static void symbol__free_source_line(struct symbol *sym, int len)
{
struct annotation *notes = symbol__annotation(sym);
@@ -929,6 +976,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
struct source_line *src_line;
struct annotation *notes = symbol__annotation(sym);
struct sym_hist *h = annotation__histogram(notes, evidx);
+ struct rb_root tmp_root = RB_ROOT;
if (!h->sum)
return 0;
@@ -963,12 +1011,13 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
goto next;
strcpy(src_line[i].path, path);
- insert_source_line(root, &src_line[i]);
+ insert_source_line(&tmp_root, &src_line[i]);
next:
pclose(fp);
}
+ resort_source_line(root, &tmp_root);
return 0;
}
@@ -992,7 +1041,7 @@ static void print_summary(struct rb_root *root, const char *filename)
char *path;
src_line = rb_entry(node, struct source_line, node);
- percent = src_line->percent;
+ percent = src_line->percent_sum;
color = get_percent_color(percent);
path = src_line->path;
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index c6272011625a..8eec94358a4a 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -76,6 +76,7 @@ struct sym_hist {
struct source_line {
struct rb_node node;
double percent;
+ double percent_sum;
char *path;
};
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/13] perf annotate: Don't try to follow jump target on PLT symbols
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (2 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 03/13] perf annotate: Merge same lines in summary view Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-14 7:43 ` [tip:perf/core] perf annotate: Don' t " tip-bot for Namhyung Kim
2012-11-09 17:27 ` [PATCH 05/13] perf annotate: Pass evsel instead of evidx on annotation functions Namhyung Kim
` (8 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
The perf annotate browser on TUI can identify a jump target for a
selected instruction. It assumes that the jump target is within the
function but it's not the case of PLT symbols which have offset out of
the function as a target. Since it caused a segmentation fault, do
not try to follow jump target on the PLT symbols.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/ui/browsers/annotate.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index aec11f34d394..bb393dd26ba2 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -190,6 +190,12 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
struct disasm_line *cursor = ab->selection, *target;
struct browser_disasm_line *btarget, *bcursor;
unsigned int from, to;
+ struct map_symbol *ms = ab->b.priv;
+ struct symbol *sym = ms->sym;
+
+ /* PLT symbols contain external offsets */
+ if (strstr(sym->name, "@plt"))
+ return;
if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) ||
!disasm_line__has_offset(cursor))
@@ -773,6 +779,12 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser
size_t size)
{
u64 offset;
+ struct map_symbol *ms = browser->b.priv;
+ struct symbol *sym = ms->sym;
+
+ /* PLT symbols contain external offsets */
+ if (strstr(sym->name, "@plt"))
+ return;
for (offset = 0; offset < size; ++offset) {
struct disasm_line *dl = browser->offsets[offset], *dlt;
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/13] perf annotate: Pass evsel instead of evidx on annotation functions
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (3 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 04/13] perf annotate: Don't try to follow jump target on PLT symbols Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 06/13] perf annotate: Factor out disasm__calc_percent() Namhyung Kim
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
Pass evsel instead of evidx. This is a preparation for supporting
event group view in annotation and no functional change is intended.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/builtin-annotate.c | 14 ++++++++------
tools/perf/builtin-top.c | 2 +-
tools/perf/ui/browsers/annotate.c | 30 +++++++++++++++++-------------
tools/perf/ui/browsers/hists.c | 2 +-
tools/perf/util/annotate.c | 33 ++++++++++++++++++---------------
tools/perf/util/annotate.h | 17 +++++++++--------
tools/perf/util/hist.h | 5 +++--
7 files changed, 57 insertions(+), 46 deletions(-)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index dc870cf31b79..0c6edd60d67e 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -108,14 +108,16 @@ static int process_sample_event(struct perf_tool *tool,
return 0;
}
-static int hist_entry__tty_annotate(struct hist_entry *he, int evidx,
+static int hist_entry__tty_annotate(struct hist_entry *he,
+ struct perf_evsel *evsel,
struct perf_annotate *ann)
{
- return symbol__tty_annotate(he->ms.sym, he->ms.map, evidx,
+ return symbol__tty_annotate(he->ms.sym, he->ms.map, evsel,
ann->print_line, ann->full_paths, 0, 0);
}
-static void hists__find_annotations(struct hists *self, int evidx,
+static void hists__find_annotations(struct hists *self,
+ struct perf_evsel *evsel,
struct perf_annotate *ann)
{
struct rb_node *nd = rb_first(&self->entries), *next;
@@ -139,7 +141,7 @@ find_next:
}
if (use_browser > 0) {
- key = hist_entry__tui_annotate(he, evidx, NULL);
+ key = hist_entry__tui_annotate(he, evsel, NULL);
switch (key) {
case K_RIGHT:
next = rb_next(nd);
@@ -154,7 +156,7 @@ find_next:
if (next != NULL)
nd = next;
} else {
- hist_entry__tty_annotate(he, evidx, ann);
+ hist_entry__tty_annotate(he, evsel, ann);
nd = rb_next(nd);
/*
* Since we have a hist_entry per IP for the same
@@ -216,7 +218,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
total_nr_samples += nr_samples;
hists__collapse_resort(hists);
hists__output_resort(hists);
- hists__find_annotations(hists, pos->idx, ann);
+ hists__find_annotations(hists, pos, ann);
}
}
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index c9ff3950cd4b..16d5ef1bd1b9 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -251,7 +251,7 @@ static void perf_top__show_details(struct perf_top *top)
printf("Showing %s for %s\n", perf_evsel__name(top->sym_evsel), symbol->name);
printf(" Events Pcnt (>=%d%%)\n", top->sym_pcnt_filter);
- more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel->idx,
+ more = symbol__annotate_printf(symbol, he->ms.map, top->sym_evsel,
0, top->sym_pcnt_filter, top->print_entries, 4);
if (top->zero)
symbol__annotate_zero_histogram(symbol, top->sym_evsel->idx);
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index bb393dd26ba2..ad943164ece9 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -8,6 +8,7 @@
#include "../../util/hist.h"
#include "../../util/sort.h"
#include "../../util/symbol.h"
+#include "../../util/evsel.h"
#include <pthread.h>
#include <newt.h>
@@ -324,7 +325,7 @@ static void annotate_browser__set_rb_top(struct annotate_browser *browser,
}
static void annotate_browser__calc_percent(struct annotate_browser *browser,
- int evidx)
+ struct perf_evsel *evsel)
{
struct map_symbol *ms = browser->b.priv;
struct symbol *sym = ms->sym;
@@ -337,7 +338,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
list_for_each_entry(pos, ¬es->src->source, node) {
struct browser_disasm_line *bpos = disasm_line__browser(pos);
- bpos->percent = disasm_line__calc_percent(pos, sym, evidx);
+ bpos->percent = disasm_line__calc_percent(pos, sym, evsel->idx);
if (bpos->percent < 0.01) {
RB_CLEAR_NODE(&bpos->rb_node);
continue;
@@ -394,7 +395,8 @@ static void annotate_browser__init_asm_mode(struct annotate_browser *browser)
browser->b.nr_entries = browser->nr_asm_entries;
}
-static bool annotate_browser__callq(struct annotate_browser *browser, int evidx,
+static bool annotate_browser__callq(struct annotate_browser *browser,
+ struct perf_evsel *evsel,
struct hist_browser_timer *hbt)
{
struct map_symbol *ms = browser->b.priv;
@@ -425,7 +427,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, int evidx,
}
pthread_mutex_unlock(¬es->lock);
- symbol__tui_annotate(target, ms->map, evidx, hbt);
+ symbol__tui_annotate(target, ms->map, evsel, hbt);
ui_browser__show_title(&browser->b, sym->name);
return true;
}
@@ -608,7 +610,8 @@ static void annotate_browser__update_addr_width(struct annotate_browser *browser
browser->addr_width += browser->jumps_width + 1;
}
-static int annotate_browser__run(struct annotate_browser *browser, int evidx,
+static int annotate_browser__run(struct annotate_browser *browser,
+ struct perf_evsel *evsel,
struct hist_browser_timer *hbt)
{
struct rb_node *nd = NULL;
@@ -621,7 +624,7 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx,
if (ui_browser__show(&browser->b, sym->name, help) < 0)
return -1;
- annotate_browser__calc_percent(browser, evidx);
+ annotate_browser__calc_percent(browser, evsel);
if (browser->curr_hot) {
annotate_browser__set_rb_top(browser, browser->curr_hot);
@@ -634,7 +637,7 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx,
key = ui_browser__run(&browser->b, delay_secs);
if (delay_secs != 0) {
- annotate_browser__calc_percent(browser, evidx);
+ annotate_browser__calc_percent(browser, evsel);
/*
* Current line focus got out of the list of most active
* lines, NULL it so that if TAB|UNTAB is pressed, we
@@ -650,7 +653,7 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx,
hbt->timer(hbt->arg);
if (delay_secs != 0)
- symbol__annotate_decay_histogram(sym, evidx);
+ symbol__annotate_decay_histogram(sym, evsel->idx);
continue;
case K_TAB:
if (nd != NULL) {
@@ -747,7 +750,7 @@ show_help:
goto show_sup_ins;
goto out;
} else if (!(annotate_browser__jump(browser) ||
- annotate_browser__callq(browser, evidx, hbt))) {
+ annotate_browser__callq(browser, evsel, hbt))) {
show_sup_ins:
ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions.");
}
@@ -769,10 +772,10 @@ out:
return key;
}
-int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
+int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
struct hist_browser_timer *hbt)
{
- return symbol__tui_annotate(he->ms.sym, he->ms.map, evidx, hbt);
+ return symbol__tui_annotate(he->ms.sym, he->ms.map, evsel, hbt);
}
static void annotate_browser__mark_jump_targets(struct annotate_browser *browser,
@@ -827,7 +830,8 @@ static inline int width_jumps(int n)
return 1;
}
-int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
+int symbol__tui_annotate(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel,
struct hist_browser_timer *hbt)
{
struct disasm_line *pos, *n;
@@ -910,7 +914,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
annotate_browser__update_addr_width(&browser);
- ret = annotate_browser__run(&browser, evidx, hbt);
+ ret = annotate_browser__run(&browser, evsel, hbt);
list_for_each_entry_safe(pos, n, ¬es->src->source, node) {
list_del(&pos->node);
disasm_line__free(pos);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 893c07f172f5..a1229a449fa5 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1439,7 +1439,7 @@ do_annotate:
* Don't let this be freed, say, by hists__decay_entry.
*/
he->used = true;
- err = hist_entry__tui_annotate(he, evsel->idx, hbt);
+ err = hist_entry__tui_annotate(he, evsel, hbt);
he->used = false;
/*
* offer option to annotate the other branch source or target
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 0ac9cc4c5e7d..3a088a367c52 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -14,6 +14,7 @@
#include "symbol.h"
#include "debug.h"
#include "annotate.h"
+#include "evsel.h"
#include <pthread.h>
#include <linux/bitops.h>
@@ -635,7 +636,7 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa
}
static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 start,
- int evidx, u64 len, int min_pcnt, int printed,
+ struct perf_evsel *evsel, u64 len, int min_pcnt, int printed,
int max_lines, struct disasm_line *queue)
{
static const char *prev_line;
@@ -648,7 +649,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
const char *color;
struct annotation *notes = symbol__annotation(sym);
struct source_line *src_line = notes->src->lines;
- struct sym_hist *h = annotation__histogram(notes, evidx);
+ struct sym_hist *h = annotation__histogram(notes, evsel->idx);
s64 offset = dl->offset;
const u64 addr = start + offset;
struct disasm_line *next;
@@ -680,7 +681,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
list_for_each_entry_from(queue, ¬es->src->source, node) {
if (queue == dl)
break;
- disasm_line__print(queue, sym, start, evidx, len,
+ disasm_line__print(queue, sym, start, evsel, len,
0, 0, 1, NULL);
}
}
@@ -967,7 +968,8 @@ static void symbol__free_source_line(struct symbol *sym, int len)
/* Get the filename:line for the colored entries */
static int symbol__get_source_line(struct symbol *sym, struct map *map,
- int evidx, struct rb_root *root, int len,
+ struct perf_evsel *evsel,
+ struct rb_root *root, int len,
const char *filename)
{
u64 start;
@@ -975,7 +977,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
char cmd[PATH_MAX * 2];
struct source_line *src_line;
struct annotation *notes = symbol__annotation(sym);
- struct sym_hist *h = annotation__histogram(notes, evidx);
+ struct sym_hist *h = annotation__histogram(notes, evsel->idx);
struct rb_root tmp_root = RB_ROOT;
if (!h->sum)
@@ -1050,10 +1052,10 @@ static void print_summary(struct rb_root *root, const char *filename)
}
}
-static void symbol__annotate_hits(struct symbol *sym, int evidx)
+static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel)
{
struct annotation *notes = symbol__annotation(sym);
- struct sym_hist *h = annotation__histogram(notes, evidx);
+ struct sym_hist *h = annotation__histogram(notes, evsel->idx);
u64 len = symbol__size(sym), offset;
for (offset = 0; offset < len; ++offset)
@@ -1063,9 +1065,9 @@ static void symbol__annotate_hits(struct symbol *sym, int evidx)
printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
}
-int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
- bool full_paths, int min_pcnt, int max_lines,
- int context)
+int symbol__annotate_printf(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel, bool full_paths,
+ int min_pcnt, int max_lines, int context)
{
struct dso *dso = map->dso;
char *filename;
@@ -1092,7 +1094,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
printf("------------------------------------------------\n");
if (verbose)
- symbol__annotate_hits(sym, evidx);
+ symbol__annotate_hits(sym, evsel);
list_for_each_entry(pos, ¬es->src->source, node) {
if (context && queue == NULL) {
@@ -1100,7 +1102,7 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
queue_len = 0;
}
- switch (disasm_line__print(pos, sym, start, evidx, len,
+ switch (disasm_line__print(pos, sym, start, evsel, len,
min_pcnt, printed, max_lines,
queue)) {
case 0:
@@ -1195,7 +1197,8 @@ size_t disasm__fprintf(struct list_head *head, FILE *fp)
return printed;
}
-int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
+int symbol__tty_annotate(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel,
bool print_lines, bool full_paths, int min_pcnt,
int max_lines)
{
@@ -1210,12 +1213,12 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
len = symbol__size(sym);
if (print_lines) {
- symbol__get_source_line(sym, map, evidx, &source_line,
+ symbol__get_source_line(sym, map, evsel, &source_line,
len, filename);
print_summary(&source_line, filename);
}
- symbol__annotate_printf(sym, map, evidx, full_paths,
+ symbol__annotate_printf(sym, map, evsel, full_paths,
min_pcnt, max_lines, 0);
if (print_lines)
symbol__free_source_line(sym, len);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 8eec94358a4a..5ce9ff3ffcd7 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -129,24 +129,25 @@ void symbol__annotate_zero_histograms(struct symbol *sym);
int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize);
int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym);
-int symbol__annotate_printf(struct symbol *sym, struct map *map, int evidx,
- bool full_paths, int min_pcnt, int max_lines,
- int context);
+int symbol__annotate_printf(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel, bool full_paths,
+ int min_pcnt, int max_lines, int context);
void symbol__annotate_zero_histogram(struct symbol *sym, int evidx);
void symbol__annotate_decay_histogram(struct symbol *sym, int evidx);
void disasm__purge(struct list_head *head);
-int symbol__tty_annotate(struct symbol *sym, struct map *map, int evidx,
- bool print_lines, bool full_paths, int min_pcnt,
- int max_lines);
+int symbol__tty_annotate(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel, bool print_lines,
+ bool full_paths, int min_pcnt, int max_lines);
#ifdef NEWT_SUPPORT
-int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
+int symbol__tui_annotate(struct symbol *sym, struct map *map,
+ struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
#else
static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
struct map *map __maybe_unused,
- int evidx __maybe_unused,
+ struct perf_evsel *evsel __maybe_unused,
struct hist_browser_timer *hbt
__maybe_unused)
{
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 99ac4d34c917..71035cea22ae 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -167,7 +167,7 @@ struct hist_browser_timer {
#ifdef NEWT_SUPPORT
#include "../ui/keysyms.h"
-int hist_entry__tui_annotate(struct hist_entry *he, int evidx,
+int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
struct hist_browser_timer *hbt);
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
@@ -186,7 +186,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
static inline int hist_entry__tui_annotate(struct hist_entry *self
__maybe_unused,
- int evidx __maybe_unused,
+ struct perf_evsel *evsel
+ __maybe_unused,
struct hist_browser_timer *hbt
__maybe_unused)
{
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/13] perf annotate: Factor out disasm__calc_percent()
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (4 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 05/13] perf annotate: Pass evsel instead of evidx on annotation functions Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 07/13] perf annotate: Basic support for event group view Namhyung Kim
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
Factor out calculation of histogram of a symbol into
disasm__calc_percent. It'll be used for event group view.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/util/annotate.c | 52 +++++++++++++++++++++++++++++---------------
1 file changed, 35 insertions(+), 17 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 3a088a367c52..f985866304ff 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -635,6 +635,38 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa
return NULL;
}
+static void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
+ s64 from, s64 to, const char **path,
+ double *percent)
+{
+ struct annotation *notes = symbol__annotation(sym);
+ struct source_line *src_line = notes->src->lines;
+ struct sym_hist *h;
+ unsigned int hits = 0;
+ s64 offset = from;
+
+ *percent = 0.0;
+
+ if (src_line) {
+ while (offset < to) {
+ if (*path == NULL)
+ *path = src_line[offset].path;
+
+ *percent += src_line[offset].percent;
+ ++offset;
+ }
+ } else {
+ h = annotation__histogram(notes, evsel->idx);
+
+ while (offset < to) {
+ hits += h->addr[offset];
+ }
+
+ if (h->sum)
+ *percent = 100.0 * hits / h->sum;
+ }
+}
+
static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 start,
struct perf_evsel *evsel, u64 len, int min_pcnt, int printed,
int max_lines, struct disasm_line *queue)
@@ -644,32 +676,18 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
if (dl->offset != -1) {
const char *path = NULL;
- unsigned int hits = 0;
double percent = 0.0;
const char *color;
struct annotation *notes = symbol__annotation(sym);
- struct source_line *src_line = notes->src->lines;
- struct sym_hist *h = annotation__histogram(notes, evsel->idx);
s64 offset = dl->offset;
const u64 addr = start + offset;
struct disasm_line *next;
next = disasm__get_next_ip_line(¬es->src->source, dl);
- while (offset < (s64)len &&
- (next == NULL || offset < next->offset)) {
- if (src_line) {
- if (path == NULL)
- path = src_line[offset].path;
- percent += src_line[offset].percent;
- } else
- hits += h->addr[offset];
-
- ++offset;
- }
-
- if (src_line == NULL && h->sum)
- percent = 100.0 * hits / h->sum;
+ disasm__calc_percent(sym, evsel, offset,
+ next ? next->offset : (s64) len,
+ &path, &percent);
if (percent < min_pcnt)
return -1;
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/13] perf annotate: Basic support for event group view
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (5 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 06/13] perf annotate: Factor out disasm__calc_percent() Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 08/13] perf annotate: Factor out struct source_line_percent Namhyung Kim
` (5 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
Add support for event group view when symbol_conf.event_group enabled.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/util/annotate.c | 86 +++++++++++++++++++++++++++++++++++---------
1 file changed, 69 insertions(+), 17 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index f985866304ff..5b44c3b1a166 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -637,15 +637,17 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa
static void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
s64 from, s64 to, const char **path,
- double *percent)
+ double *percent, int nr_percent)
{
struct annotation *notes = symbol__annotation(sym);
struct source_line *src_line = notes->src->lines;
struct sym_hist *h;
- unsigned int hits = 0;
+ unsigned int hits;
s64 offset = from;
+ int evidx = evsel->idx;
+ int i;
- *percent = 0.0;
+ memset(percent, 0, sizeof(percent) * nr_percent);
if (src_line) {
while (offset < to) {
@@ -656,14 +658,19 @@ static void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
++offset;
}
} else {
- h = annotation__histogram(notes, evsel->idx);
+ for (i = 0; i < nr_percent; i++) {
+ hits = 0;
+ offset = from;
+ h = annotation__histogram(notes, evidx + i);
+
+ while (offset < to) {
+ hits += h->addr[offset];
+ offset++;
+ }
- while (offset < to) {
- hits += h->addr[offset];
+ if (h->sum)
+ percent[i] = 100.0 * hits / h->sum;
}
-
- if (h->sum)
- *percent = 100.0 * hits / h->sum;
}
}
@@ -677,19 +684,39 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
if (dl->offset != -1) {
const char *path = NULL;
double percent = 0.0;
+ double percent_max = 0.0;
+ double *ppercents = &percent;
+ int i, nr_percents = 1;
const char *color;
struct annotation *notes = symbol__annotation(sym);
s64 offset = dl->offset;
const u64 addr = start + offset;
struct disasm_line *next;
+ if (symbol_conf.event_group) {
+ if (perf_evsel__is_group_leader(evsel) &&
+ evsel->nr_members > 0) {
+ nr_percents = evsel->nr_members + 1;
+ ppercents = calloc(nr_percents, sizeof(double));
+ if (ppercents == NULL)
+ return -1;
+ }
+ }
+
next = disasm__get_next_ip_line(¬es->src->source, dl);
disasm__calc_percent(sym, evsel, offset,
next ? next->offset : (s64) len,
- &path, &percent);
+ &path, ppercents, nr_percents);
+
+ for (i = 0; i < nr_percents; i++) {
+ percent = ppercents[i];
+
+ if (percent > percent_max)
+ percent_max = percent;
+ }
- if (percent < min_pcnt)
+ if (percent_max < min_pcnt)
return -1;
if (max_lines && printed >= max_lines)
@@ -704,7 +731,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
}
}
- color = get_percent_color(percent);
+ color = get_percent_color(percent_max);
/*
* Also color the filename and line if needed, with
@@ -720,20 +747,35 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st
}
}
- color_fprintf(stdout, color, " %7.2f", percent);
+ for (i = 0; i < nr_percents; i++) {
+ percent = ppercents[i];
+ color = get_percent_color(percent);
+ color_fprintf(stdout, color, " %7.2f", percent);
+ }
+
printf(" : ");
color_fprintf(stdout, PERF_COLOR_MAGENTA, " %" PRIx64 ":", addr);
color_fprintf(stdout, PERF_COLOR_BLUE, "%s\n", dl->line);
+
+ if (ppercents != &percent)
+ free(ppercents);
} else if (max_lines && printed >= max_lines)
return 1;
else {
+ int width = 8;
+
if (queue)
return -1;
+ if (symbol_conf.event_group) {
+ if (perf_evsel__is_group_leader(evsel))
+ width *= evsel->nr_members + 1;
+ }
+
if (!*dl->line)
- printf(" :\n");
+ printf(" %*s:\n", width, " ");
else
- printf(" : %s\n", dl->line);
+ printf(" %*s: %s\n", width, " ", dl->line);
}
return 0;
@@ -1096,6 +1138,8 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
int printed = 2, queue_len = 0;
int more = 0;
u64 len;
+ int width = 8;
+ int namelen;
filename = strdup(dso->long_name);
if (!filename)
@@ -1108,8 +1152,16 @@ int symbol__annotate_printf(struct symbol *sym, struct map *map,
len = symbol__size(sym);
- printf(" Percent | Source code & Disassembly of %s\n", d_filename);
- printf("------------------------------------------------\n");
+ if (symbol_conf.event_group) {
+ if (perf_evsel__is_group_leader(evsel))
+ width *= evsel->nr_members + 1;
+ }
+ namelen = strlen(d_filename);
+
+ printf(" %-*.*s| Source code & Disassembly of %s\n",
+ width, width, "Percent", d_filename);
+ printf("-%-*.*s-------------------------------------\n",
+ width + namelen, width + namelen, graph_dotted_line);
if (verbose)
symbol__annotate_hits(sym, evsel);
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/13] perf annotate: Factor out struct source_line_percent
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (6 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 07/13] perf annotate: Basic support for event group view Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 09/13] perf annotate: Support event group view for --print-line Namhyung Kim
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
The source_line_percent struct contains percentage value of the symbol
histogram. This is a preparation of event group view change.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/ui/browsers/annotate.c | 2 +-
tools/perf/util/annotate.c | 14 +++++++-------
tools/perf/util/annotate.h | 8 ++++++--
3 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index ad943164ece9..feea37ad37e9 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -250,7 +250,7 @@ static double disasm_line__calc_percent(struct disasm_line *dl, struct symbol *s
while (offset < (s64)len &&
(next == NULL || offset < next->offset)) {
if (src_line) {
- percent += src_line[offset].percent;
+ percent += src_line[offset].p[0].percent;
} else
hits += h->addr[offset];
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 5b44c3b1a166..42f8a9d8a9cf 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -654,7 +654,7 @@ static void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
if (*path == NULL)
*path = src_line[offset].path;
- *percent += src_line[offset].percent;
+ *percent += src_line[offset].p[0].percent;
++offset;
}
} else {
@@ -959,7 +959,7 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
ret = strcmp(iter->path, src_line->path);
if (ret == 0) {
- iter->percent_sum += src_line->percent;
+ iter->p[0].percent_sum += src_line->p[0].percent;
return;
}
@@ -969,7 +969,7 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
p = &(*p)->rb_right;
}
- src_line->percent_sum = src_line->percent;
+ src_line->p[0].percent_sum = src_line->p[0].percent;
rb_link_node(&src_line->node, parent, p);
rb_insert_color(&src_line->node, root);
@@ -985,7 +985,7 @@ static void __resort_source_line(struct rb_root *root, struct source_line *src_l
parent = *p;
iter = rb_entry(parent, struct source_line, node);
- if (src_line->percent_sum > iter->percent_sum)
+ if (src_line->p[0].percent_sum > iter->p[0].percent_sum)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -1055,8 +1055,8 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
u64 offset;
FILE *fp;
- src_line[i].percent = 100.0 * h->addr[i] / h->sum;
- if (src_line[i].percent <= 0.5)
+ src_line[i].p[0].percent = 100.0 * h->addr[i] / h->sum;
+ if (src_line[i].p[0].percent <= 0.5)
continue;
offset = start + i;
@@ -1103,7 +1103,7 @@ static void print_summary(struct rb_root *root, const char *filename)
char *path;
src_line = rb_entry(node, struct source_line, node);
- percent = src_line->percent_sum;
+ percent = src_line->p[0].percent_sum;
color = get_percent_color(percent);
path = src_line->path;
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index 5ce9ff3ffcd7..ca2badc07653 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -73,11 +73,15 @@ struct sym_hist {
u64 addr[0];
};
-struct source_line {
- struct rb_node node;
+struct source_line_percent {
double percent;
double percent_sum;
+};
+
+struct source_line {
+ struct rb_node node;
char *path;
+ struct source_line_percent p[1];
};
/** struct annotated_source - symbols with hits have this attached as in sannotation
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/13] perf annotate: Support event group view for --print-line
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (7 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 08/13] perf annotate: Factor out struct source_line_percent Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 10/13] perf annotate browser: Make browser_disasm_line->percent an array Namhyung Kim
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML
Dynamically allocate source_line_percent according to a number of
group members and save nr_pcnt to the struct source_line. This
way we can handle multiple events in a general manner.
However since the size of struct source_line is not fixed anymore,
iterating whole source_line should care about its size.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/util/annotate.c | 123 +++++++++++++++++++++++++++++++++-----------
tools/perf/util/annotate.h | 1 +
2 files changed, 95 insertions(+), 29 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 42f8a9d8a9cf..28ac33e83bf3 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -650,11 +650,19 @@ static void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
memset(percent, 0, sizeof(percent) * nr_percent);
if (src_line) {
+ size_t sizeof_src_line = sizeof(*src_line) +
+ sizeof(src_line->p) * (src_line->nr_pcnt - 1);
+
while (offset < to) {
- if (*path == NULL)
- *path = src_line[offset].path;
+ src_line = (void *)notes->src->lines +
+ (sizeof_src_line * offset);
+
+ if (path && *path == NULL)
+ *path = src_line->path;
+
+ for (i = 0; i < nr_percent; i++)
+ percent[i] += src_line->p[i].percent;
- *percent += src_line[offset].p[0].percent;
++offset;
}
} else {
@@ -951,7 +959,7 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
struct source_line *iter;
struct rb_node **p = &root->rb_node;
struct rb_node *parent = NULL;
- int ret;
+ int i, ret;
while (*p != NULL) {
parent = *p;
@@ -959,7 +967,8 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
ret = strcmp(iter->path, src_line->path);
if (ret == 0) {
- iter->p[0].percent_sum += src_line->p[0].percent;
+ for (i = 0; i < src_line->nr_pcnt; i++)
+ iter->p[i].percent_sum += src_line->p[i].percent;
return;
}
@@ -969,12 +978,26 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin
p = &(*p)->rb_right;
}
- src_line->p[0].percent_sum = src_line->p[0].percent;
+ for (i = 0; i < src_line->nr_pcnt; i++)
+ src_line->p[i].percent_sum = src_line->p[i].percent;
rb_link_node(&src_line->node, parent, p);
rb_insert_color(&src_line->node, root);
}
+static int cmp_source_line(struct source_line *a, struct source_line *b)
+{
+ int i;
+
+ for (i = 0; i < a->nr_pcnt; i++) {
+ if (a->p[i].percent_sum == b->p[i].percent_sum)
+ continue;
+ return a->p[i].percent_sum > b->p[i].percent_sum;
+ }
+
+ return 0;
+}
+
static void __resort_source_line(struct rb_root *root, struct source_line *src_line)
{
struct source_line *iter;
@@ -985,7 +1008,7 @@ static void __resort_source_line(struct rb_root *root, struct source_line *src_l
parent = *p;
iter = rb_entry(parent, struct source_line, node);
- if (src_line->p[0].percent_sum > iter->p[0].percent_sum)
+ if (cmp_source_line(src_line, iter))
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -1017,12 +1040,18 @@ static void symbol__free_source_line(struct symbol *sym, int len)
{
struct annotation *notes = symbol__annotation(sym);
struct source_line *src_line = notes->src->lines;
+ size_t sizeof_src_line;
int i;
- for (i = 0; i < len; i++)
- free(src_line[i].path);
+ sizeof_src_line = sizeof(*src_line) +
+ (sizeof(src_line->p) * (src_line->nr_pcnt - 1));
- free(src_line);
+ for (i = 0; i < len; i++) {
+ free(src_line->path);
+ src_line = (void *)src_line + sizeof_src_line;
+ }
+
+ free(notes->src->lines);
notes->src->lines = NULL;
}
@@ -1033,17 +1062,32 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
const char *filename)
{
u64 start;
- int i;
+ int i, k;
+ int evidx = evsel->idx;
char cmd[PATH_MAX * 2];
struct source_line *src_line;
struct annotation *notes = symbol__annotation(sym);
- struct sym_hist *h = annotation__histogram(notes, evsel->idx);
+ struct sym_hist *h = annotation__histogram(notes, evidx);
struct rb_root tmp_root = RB_ROOT;
+ int nr_pcnt = 1;
+ u64 h_sum = h->sum;
+ size_t sizeof_src_line = sizeof(struct source_line);
- if (!h->sum)
+ if (symbol_conf.event_group) {
+ if (perf_evsel__is_group_leader(evsel)) {
+ for (i = 0; i < evsel->nr_members; i++) {
+ h = annotation__histogram(notes, evidx + i);
+ h_sum += h->sum;
+ }
+ nr_pcnt += evsel->nr_members;
+ sizeof_src_line += (nr_pcnt - 1) * sizeof(src_line->p);
+ }
+ }
+
+ if (!h_sum)
return 0;
- src_line = notes->src->lines = calloc(len, sizeof(struct source_line));
+ src_line = notes->src->lines = calloc(len, sizeof_src_line);
if (!notes->src->lines)
return -1;
@@ -1054,29 +1098,41 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
size_t line_len;
u64 offset;
FILE *fp;
+ double percent_max = 0.0;
- src_line[i].p[0].percent = 100.0 * h->addr[i] / h->sum;
- if (src_line[i].p[0].percent <= 0.5)
- continue;
+ src_line->nr_pcnt = nr_pcnt;
+
+ for (k = 0; k < nr_pcnt; k++) {
+ h = annotation__histogram(notes, evidx + k);
+ src_line->p[k].percent = 100.0 * h->addr[i] / h->sum;
+
+ if (src_line->p[k].percent > percent_max)
+ percent_max = src_line->p[k].percent;
+ }
+
+ if (percent_max <= 0.5)
+ goto next;
offset = start + i;
sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
fp = popen(cmd, "r");
if (!fp)
- continue;
+ goto next;
if (getline(&path, &line_len, fp) < 0 || !line_len)
- goto next;
+ goto next_close;
- src_line[i].path = malloc(sizeof(char) * line_len + 1);
- if (!src_line[i].path)
- goto next;
+ src_line->path = malloc(sizeof(char) * line_len + 1);
+ if (!src_line->path)
+ goto next_close;
- strcpy(src_line[i].path, path);
- insert_source_line(&tmp_root, &src_line[i]);
+ strcpy(src_line->path, path);
+ insert_source_line(&tmp_root, src_line);
- next:
+ next_close:
pclose(fp);
+ next:
+ src_line = (void *)src_line + sizeof_src_line;
}
resort_source_line(root, &tmp_root);
@@ -1098,16 +1154,25 @@ static void print_summary(struct rb_root *root, const char *filename)
node = rb_first(root);
while (node) {
- double percent;
+ double percent, percent_max = 0.0;
const char *color;
char *path;
+ int i;
src_line = rb_entry(node, struct source_line, node);
- percent = src_line->p[0].percent_sum;
- color = get_percent_color(percent);
+ for (i = 0; i < src_line->nr_pcnt; i++) {
+ percent = src_line->p[i].percent_sum;
+ color = get_percent_color(percent);
+ color_fprintf(stdout, color, " %7.2f", percent);
+
+ if (percent > percent_max)
+ percent_max = percent;
+ }
+
path = src_line->path;
+ color = get_percent_color(percent_max);
+ color_fprintf(stdout, color, " %s", path);
- color_fprintf(stdout, color, " %7.2f %s", percent, path);
node = rb_next(node);
}
}
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index ca2badc07653..fa74c09f0c70 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -81,6 +81,7 @@ struct source_line_percent {
struct source_line {
struct rb_node node;
char *path;
+ int nr_pcnt;
struct source_line_percent p[1];
};
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/13] perf annotate browser: Make browser_disasm_line->percent an array
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (8 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 09/13] perf annotate: Support event group view for --print-line Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 11/13] perf annotate browser: Use disasm__calc_percent() Namhyung Kim
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML
Make percent field of struct browser_disasm_line an array and
move it to the last. This is a preparation of event group view
feature.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/ui/browsers/annotate.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index feea37ad37e9..a846fe36a26e 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -14,10 +14,10 @@
struct browser_disasm_line {
struct rb_node rb_node;
- double percent;
u32 idx;
int idx_asm;
int jump_sources;
+ double percent[1];
};
static struct annotate_browser_opt {
@@ -97,9 +97,9 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
int width = browser->width, printed;
char bf[256];
- if (dl->offset != -1 && bdl->percent != 0.0) {
- ui_browser__set_percent_color(browser, bdl->percent, current_entry);
- slsmg_printf("%6.2f ", bdl->percent);
+ if (dl->offset != -1 && bdl->percent[0] != 0.0) {
+ ui_browser__set_percent_color(browser, bdl->percent[0], current_entry);
+ slsmg_printf("%6.2f ", bdl->percent[0]);
} else {
ui_browser__set_percent_color(browser, 0, current_entry);
slsmg_write_nstring(" ", 7);
@@ -276,7 +276,7 @@ static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_l
while (*p != NULL) {
parent = *p;
l = rb_entry(parent, struct browser_disasm_line, rb_node);
- if (bdl->percent < l->percent)
+ if (bdl->percent[0] < l->percent[0])
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -338,8 +338,8 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
list_for_each_entry(pos, ¬es->src->source, node) {
struct browser_disasm_line *bpos = disasm_line__browser(pos);
- bpos->percent = disasm_line__calc_percent(pos, sym, evsel->idx);
- if (bpos->percent < 0.01) {
+ bpos->percent[0] = disasm_line__calc_percent(pos, sym, evsel->idx);
+ if (bpos->percent[0] < 0.01) {
RB_CLEAR_NODE(&bpos->rb_node);
continue;
}
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/13] perf annotate browser: Use disasm__calc_percent()
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (9 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 10/13] perf annotate browser: Make browser_disasm_line->percent an array Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 12/13] perf annotate browser: Support event group view on TUI Namhyung Kim
2012-11-09 17:27 ` [PATCH 13/13] perf annotate: Add --group option Namhyung Kim
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML
The disasm_line__calc_percent() which was used by annotate
browser code almost duplicates disasm__calc_percent. Since
the latter can handle multiple events properly, use it and
get rid of the code duplication.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/ui/browsers/annotate.c | 50 +++++++++++--------------------------
tools/perf/util/annotate.c | 6 ++---
tools/perf/util/annotate.h | 3 +++
3 files changed, 20 insertions(+), 39 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index a846fe36a26e..7df1fa990ec2 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -233,40 +233,6 @@ static unsigned int annotate_browser__refresh(struct ui_browser *browser)
return ret;
}
-static double disasm_line__calc_percent(struct disasm_line *dl, struct symbol *sym, int evidx)
-{
- double percent = 0.0;
-
- if (dl->offset != -1) {
- int len = sym->end - sym->start;
- unsigned int hits = 0;
- struct annotation *notes = symbol__annotation(sym);
- struct source_line *src_line = notes->src->lines;
- struct sym_hist *h = annotation__histogram(notes, evidx);
- s64 offset = dl->offset;
- struct disasm_line *next;
-
- next = disasm__get_next_ip_line(¬es->src->source, dl);
- while (offset < (s64)len &&
- (next == NULL || offset < next->offset)) {
- if (src_line) {
- percent += src_line[offset].p[0].percent;
- } else
- hits += h->addr[offset];
-
- ++offset;
- }
- /*
- * If the percentage wasn't already calculated in
- * symbol__get_source_line, do it now:
- */
- if (src_line == NULL && h->sum)
- percent = 100.0 * hits / h->sum;
- }
-
- return percent;
-}
-
static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl)
{
struct rb_node **p = &root->rb_node;
@@ -330,7 +296,8 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
struct map_symbol *ms = browser->b.priv;
struct symbol *sym = ms->sym;
struct annotation *notes = symbol__annotation(sym);
- struct disasm_line *pos;
+ struct disasm_line *pos, *next;
+ u64 len = sym->end - sym->start;
browser->entries = RB_ROOT;
@@ -338,7 +305,18 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
list_for_each_entry(pos, ¬es->src->source, node) {
struct browser_disasm_line *bpos = disasm_line__browser(pos);
- bpos->percent[0] = disasm_line__calc_percent(pos, sym, evsel->idx);
+
+ if (pos->offset == -1) {
+ RB_CLEAR_NODE(&bpos->rb_node);
+ continue;
+ }
+
+ next = disasm__get_next_ip_line(¬es->src->source, pos);
+
+ disasm__calc_percent(sym, evsel, pos->offset,
+ next ? next->offset : (s64) len,
+ NULL, bpos->percent, 1);
+
if (bpos->percent[0] < 0.01) {
RB_CLEAR_NODE(&bpos->rb_node);
continue;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 28ac33e83bf3..41462f84feea 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -635,9 +635,9 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa
return NULL;
}
-static void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
- s64 from, s64 to, const char **path,
- double *percent, int nr_percent)
+void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
+ s64 from, s64 to, const char **path,
+ double *percent, int nr_percent)
{
struct annotation *notes = symbol__annotation(sym);
struct source_line *src_line = notes->src->lines;
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index fa74c09f0c70..6cbb333ad518 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -67,6 +67,9 @@ void disasm_line__free(struct disasm_line *dl);
struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disasm_line *pos);
int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw);
size_t disasm__fprintf(struct list_head *head, FILE *fp);
+void disasm__calc_percent(struct symbol *sym, struct perf_evsel *evsel,
+ s64 from, s64 to, const char **path,
+ double *percent, int nr_percent);
struct sym_hist {
u64 sum;
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/13] perf annotate browser: Support event group view on TUI
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (10 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 11/13] perf annotate browser: Use disasm__calc_percent() Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
2012-11-09 17:27 ` [PATCH 13/13] perf annotate: Add --group option Namhyung Kim
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML
Dynamically allocate browser_disasm_line according to a number of
group members and save nr_pcnt to the struct. This way we can
handle multiple events in a general manner.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/ui/browsers/annotate.c | 69 ++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 12 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 7df1fa990ec2..0826f8954795 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -17,6 +17,7 @@ struct browser_disasm_line {
u32 idx;
int idx_asm;
int jump_sources;
+ int nr_pcnt;
double percent[1];
};
@@ -95,14 +96,25 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
(!current_entry || (browser->use_navkeypressed &&
!browser->navkeypressed)));
int width = browser->width, printed;
+ int i, pcnt_width = 7 * bdl->nr_pcnt;
+ double percent_max = 0.0;
char bf[256];
- if (dl->offset != -1 && bdl->percent[0] != 0.0) {
- ui_browser__set_percent_color(browser, bdl->percent[0], current_entry);
- slsmg_printf("%6.2f ", bdl->percent[0]);
+ for (i = 0; i < bdl->nr_pcnt; i++) {
+ if (bdl->percent[i] > percent_max)
+ percent_max = bdl->percent[i];
+ }
+
+ if (dl->offset != -1 && percent_max != 0.0) {
+ for (i = 0; i < bdl->nr_pcnt; i++) {
+ ui_browser__set_percent_color(browser,
+ bdl->percent[i],
+ current_entry);
+ slsmg_printf("%6.2f ", bdl->percent[i]);
+ }
} else {
ui_browser__set_percent_color(browser, 0, current_entry);
- slsmg_write_nstring(" ", 7);
+ slsmg_write_nstring(" ", pcnt_width);
}
SLsmg_write_char(' ');
@@ -112,14 +124,14 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
width += 1;
if (!*dl->line)
- slsmg_write_nstring(" ", width - 7);
+ slsmg_write_nstring(" ", width - pcnt_width);
else if (dl->offset == -1) {
printed = scnprintf(bf, sizeof(bf), "%*s ",
ab->addr_width, " ");
slsmg_write_nstring(bf, printed);
- slsmg_write_nstring(dl->line, width - printed - 6);
+ slsmg_write_nstring(dl->line, width - printed - pcnt_width + 1);
} else if (!dl->name) {
- slsmg_write_nstring(" ", width - 7);
+ slsmg_write_nstring(" ", width - pcnt_width);
} else {
u64 addr = dl->offset;
int color = -1;
@@ -178,7 +190,7 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int
}
disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset);
- slsmg_write_nstring(bf, width - 10 - printed);
+ slsmg_write_nstring(bf, width - pcnt_width - 3 - printed);
}
if (current_entry)
@@ -193,6 +205,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
unsigned int from, to;
struct map_symbol *ms = ab->b.priv;
struct symbol *sym = ms->sym;
+ u8 pcnt_width = 7;
/* PLT symbols contain external offsets */
if (strstr(sym->name, "@plt"))
@@ -217,22 +230,43 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
to = (u64)btarget->idx;
}
+ pcnt_width *= bcursor->nr_pcnt;
+
ui_browser__set_color(browser, HE_COLORSET_CODE);
- __ui_browser__line_arrow(browser, 9 + ab->addr_width, from, to);
+ __ui_browser__line_arrow(browser, pcnt_width + 2 + ab->addr_width,
+ from, to);
}
static unsigned int annotate_browser__refresh(struct ui_browser *browser)
{
+ struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
+ struct disasm_line *cursor = ab->offsets[0];
+ struct browser_disasm_line *bcursor = disasm_line__browser(cursor);
int ret = ui_browser__list_head_refresh(browser);
+ int pcnt_width = 7 * bcursor->nr_pcnt;
if (annotate_browser__opts.jump_arrows)
annotate_browser__draw_current_jump(browser);
ui_browser__set_color(browser, HE_COLORSET_NORMAL);
- __ui_browser__vline(browser, 7, 0, browser->height - 1);
+ __ui_browser__vline(browser, pcnt_width, 0, browser->height - 1);
return ret;
}
+static int disasm__cmp(struct browser_disasm_line *a,
+ struct browser_disasm_line *b)
+{
+ int i;
+
+ for (i = 0; i < a->nr_pcnt; i++) {
+ if (a->percent[i] == b->percent[i])
+ continue;
+ return a->percent[i] < b->percent[i];
+ }
+
+ return 0;
+}
+
static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_line *bdl)
{
struct rb_node **p = &root->rb_node;
@@ -242,7 +276,8 @@ static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_l
while (*p != NULL) {
parent = *p;
l = rb_entry(parent, struct browser_disasm_line, rb_node);
- if (bdl->percent[0] < l->percent[0])
+
+ if (disasm__cmp(bdl, l))
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -830,6 +865,8 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
},
};
int ret = -1;
+ int nr_pcnt = 1;
+ size_t sizeof_bdl = sizeof(struct browser_disasm_line);
if (sym == NULL)
return -1;
@@ -845,7 +882,14 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
return -1;
}
- if (symbol__annotate(sym, map, sizeof(struct browser_disasm_line)) < 0) {
+ if (symbol_conf.event_group) {
+ if (perf_evsel__is_group_leader(evsel)) {
+ sizeof_bdl += sizeof(double) * evsel->nr_members;
+ nr_pcnt += evsel->nr_members;
+ }
+ }
+
+ if (symbol__annotate(sym, map, sizeof_bdl) < 0) {
ui__error("%s", ui_helpline__last_msg);
goto out_free_offsets;
}
@@ -862,6 +906,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
if (browser.b.width < line_len)
browser.b.width = line_len;
bpos = disasm_line__browser(pos);
+ bpos->nr_pcnt = nr_pcnt;
bpos->idx = browser.nr_entries++;
if (pos->offset != -1) {
bpos->idx_asm = browser.nr_asm_entries++;
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 13/13] perf annotate: Add --group option
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
` (11 preceding siblings ...)
2012-11-09 17:27 ` [PATCH 12/13] perf annotate browser: Support event group view on TUI Namhyung Kim
@ 2012-11-09 17:27 ` Namhyung Kim
12 siblings, 0 replies; 16+ messages in thread
From: Namhyung Kim @ 2012-11-09 17:27 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Ingo Molnar, Peter Zijlstra, Jiri Olsa, Stephane Eranian,
Andi Kleen, David Ahern, LKML, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
Add --group option to enable event grouping. When enabled, all the
group members information will be shown together with the leader so
skip non-leader events.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/builtin-annotate.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 0c6edd60d67e..4b12608707f0 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -214,6 +214,10 @@ static int __cmd_annotate(struct perf_annotate *ann)
struct hists *hists = &pos->hists;
u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
+ if (symbol_conf.event_group &&
+ !perf_evsel__is_group_leader(pos))
+ continue;
+
if (nr_samples > 0) {
total_nr_samples += nr_samples;
hists__collapse_resort(hists);
@@ -293,6 +297,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
"Specify disassembler style (e.g. -M intel for intel syntax)"),
OPT_STRING(0, "objdump", &objdump_path, "path",
"objdump binary to use for disassembly and annotations"),
+ OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
+ "Show event grou information together"),
OPT_END()
};
--
1.7.9.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [tip:perf/core] perf annotate: Whitespace fixups
2012-11-09 17:27 ` [PATCH 02/13] perf annotate: Whitespace fixups Namhyung Kim
@ 2012-11-14 7:42 ` tip-bot for Namhyung Kim
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Namhyung Kim @ 2012-11-14 7:42 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, peterz, namhyung, jolsa,
ak, dsahern, tglx
Commit-ID: 2ba34aaa6db8b61cf1fa14132f885ba6bc7c9ae0
Gitweb: http://git.kernel.org/tip/2ba34aaa6db8b61cf1fa14132f885ba6bc7c9ae0
Author: Namhyung Kim <namhyung@kernel.org>
AuthorDate: Sat, 10 Nov 2012 02:27:13 +0900
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 9 Nov 2012 16:22:46 -0300
perf annotate: Whitespace fixups
Some lines are indented by whitespace characters rather than tabs. Fix
them.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1352482044-3443-3-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/annotate.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index b14d4df..435bf6d 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -171,15 +171,15 @@ static int lock__parse(struct ins_operands *ops)
if (disasm_line__parse(ops->raw, &name, &ops->locked.ops->raw) < 0)
goto out_free_ops;
- ops->locked.ins = ins__find(name);
- if (ops->locked.ins == NULL)
- goto out_free_ops;
+ ops->locked.ins = ins__find(name);
+ if (ops->locked.ins == NULL)
+ goto out_free_ops;
- if (!ops->locked.ins->ops)
- return 0;
+ if (!ops->locked.ins->ops)
+ return 0;
- if (ops->locked.ins->ops->parse)
- ops->locked.ins->ops->parse(ops->locked.ops);
+ if (ops->locked.ins->ops->parse)
+ ops->locked.ins->ops->parse(ops->locked.ops);
return 0;
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [tip:perf/core] perf annotate: Don' t try to follow jump target on PLT symbols
2012-11-09 17:27 ` [PATCH 04/13] perf annotate: Don't try to follow jump target on PLT symbols Namhyung Kim
@ 2012-11-14 7:43 ` tip-bot for Namhyung Kim
0 siblings, 0 replies; 16+ messages in thread
From: tip-bot for Namhyung Kim @ 2012-11-14 7:43 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, hpa, mingo, peterz, namhyung.kim,
namhyung, jolsa, ak, dsahern, tglx
Commit-ID: 32ae1efd9d40645601cd4e09fa83a2711dd1ad6d
Gitweb: http://git.kernel.org/tip/32ae1efd9d40645601cd4e09fa83a2711dd1ad6d
Author: Namhyung Kim <namhyung.kim@lge.com>
AuthorDate: Sat, 10 Nov 2012 02:27:15 +0900
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 9 Nov 2012 16:23:21 -0300
perf annotate: Don't try to follow jump target on PLT symbols
The perf annotate browser on TUI can identify a jump target for a
selected instruction. It assumes that the jump target is within the
function but it's not the case of PLT symbols which have offset out of
the function as a target.
Since it caused a segmentation fault, do not try to follow jump target
on the PLT symbols.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1352482044-3443-5-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/ui/browsers/annotate.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 3eff17f..5dab3ca 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -188,6 +188,12 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
struct disasm_line *cursor = ab->selection, *target;
struct browser_disasm_line *btarget, *bcursor;
unsigned int from, to;
+ struct map_symbol *ms = ab->b.priv;
+ struct symbol *sym = ms->sym;
+
+ /* PLT symbols contain external offsets */
+ if (strstr(sym->name, "@plt"))
+ return;
if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) ||
!disasm_line__has_offset(cursor))
@@ -771,6 +777,12 @@ static void annotate_browser__mark_jump_targets(struct annotate_browser *browser
size_t size)
{
u64 offset;
+ struct map_symbol *ms = browser->b.priv;
+ struct symbol *sym = ms->sym;
+
+ /* PLT symbols contain external offsets */
+ if (strstr(sym->name, "@plt"))
+ return;
for (offset = 0; offset < size; ++offset) {
struct disasm_line *dl = browser->offsets[offset], *dlt;
^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2012-11-14 7:43 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-09 17:27 [PATCHSET 00/13] perf annotate: Add support for event group view (v1) Namhyung Kim
2012-11-09 17:27 ` [PATCH 01/13] perf annotate: Parse --asm-raw output properly Namhyung Kim
2012-11-09 17:27 ` [PATCH 02/13] perf annotate: Whitespace fixups Namhyung Kim
2012-11-14 7:42 ` [tip:perf/core] " tip-bot for Namhyung Kim
2012-11-09 17:27 ` [PATCH 03/13] perf annotate: Merge same lines in summary view Namhyung Kim
2012-11-09 17:27 ` [PATCH 04/13] perf annotate: Don't try to follow jump target on PLT symbols Namhyung Kim
2012-11-14 7:43 ` [tip:perf/core] perf annotate: Don' t " tip-bot for Namhyung Kim
2012-11-09 17:27 ` [PATCH 05/13] perf annotate: Pass evsel instead of evidx on annotation functions Namhyung Kim
2012-11-09 17:27 ` [PATCH 06/13] perf annotate: Factor out disasm__calc_percent() Namhyung Kim
2012-11-09 17:27 ` [PATCH 07/13] perf annotate: Basic support for event group view Namhyung Kim
2012-11-09 17:27 ` [PATCH 08/13] perf annotate: Factor out struct source_line_percent Namhyung Kim
2012-11-09 17:27 ` [PATCH 09/13] perf annotate: Support event group view for --print-line Namhyung Kim
2012-11-09 17:27 ` [PATCH 10/13] perf annotate browser: Make browser_disasm_line->percent an array Namhyung Kim
2012-11-09 17:27 ` [PATCH 11/13] perf annotate browser: Use disasm__calc_percent() Namhyung Kim
2012-11-09 17:27 ` [PATCH 12/13] perf annotate browser: Support event group view on TUI Namhyung Kim
2012-11-09 17:27 ` [PATCH 13/13] perf annotate: Add --group option Namhyung Kim
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.