linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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, &notes->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(&notes->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, &notes->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, &notes->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, &notes->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(&notes->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(&notes->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, &notes->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(&notes->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, &notes->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(&notes->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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).