Skip to content

Commit

Permalink
perf report: Print sorted callchains per histogram entries
Browse files Browse the repository at this point in the history
Use the newly created callchains radix tree to gather the chains stats
from the recorded events and then print the callchains for all of them,
sorted by hits, using the "-c" parameter with perf report.

Example:

 66.15%  [k] atm_clip_exit
            63.08%
                0xffffffffffffff80
                0xffffffff810196a8
                0xffffffff810c14c8
                0xffffffff8101a79c
                0xffffffff810194f3
                0xffffffff8106ab7f
                0xffffffff8106abe5
                0xffffffff8106acde
                0xffffffff8100d94b
                0xffffffff8153e7ea
                [...]

             1.54%
                0xffffffffffffff80
                0xffffffff810196a8
                0xffffffff810c14c8
                0xffffffff8101a79c
		[...]

Symbols are not yet resolved.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1246026481-8314-3-git-send-email-fweisbec@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Jun 26, 2009
1 parent 8cb76d9 commit f55c555
Showing 1 changed file with 71 additions and 11 deletions.
82 changes: 71 additions & 11 deletions tools/perf/builtin-report.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "util/rbtree.h"
#include "util/symbol.h"
#include "util/string.h"
#include "util/callchain.h"

#include "perf.h"
#include "util/header.h"
Expand Down Expand Up @@ -52,6 +53,7 @@ static char *parent_pattern = default_parent_pattern;
static regex_t parent_regex;

static int exclude_other = 1;
static int callchain;

static u64 sample_type;

Expand Down Expand Up @@ -488,17 +490,19 @@ static size_t threads__fprintf(FILE *fp)
static struct rb_root hist;

struct hist_entry {
struct rb_node rb_node;

struct thread *thread;
struct map *map;
struct dso *dso;
struct symbol *sym;
struct symbol *parent;
u64 ip;
char level;

u64 count;
struct rb_node rb_node;

struct thread *thread;
struct map *map;
struct dso *dso;
struct symbol *sym;
struct symbol *parent;
u64 ip;
char level;
struct callchain_node callchain;
struct rb_root sorted_chain;

u64 count;
};

/*
Expand Down Expand Up @@ -768,6 +772,48 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
return cmp;
}

static size_t
callchain__fprintf(FILE *fp, struct callchain_node *self, u64 total_samples)
{
struct callchain_list *chain;
size_t ret = 0;

if (!self)
return 0;

ret += callchain__fprintf(fp, self->parent, total_samples);


list_for_each_entry(chain, &self->val, list)
ret += fprintf(fp, " %p\n", (void *)chain->ip);

return ret;
}

static size_t
hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self,
u64 total_samples)
{
struct rb_node *rb_node;
struct callchain_node *chain;
size_t ret = 0;

rb_node = rb_first(&self->sorted_chain);
while (rb_node) {
double percent;

chain = rb_entry(rb_node, struct callchain_node, rb_node);
percent = chain->hit * 100.0 / total_samples;
ret += fprintf(fp, " %6.2f%%\n", percent);
ret += callchain__fprintf(fp, chain, total_samples);
ret += fprintf(fp, "\n");
rb_node = rb_next(rb_node);
}

return ret;
}


static size_t
hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)
{
Expand Down Expand Up @@ -808,6 +854,9 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples)

ret += fprintf(fp, "\n");

if (callchain)
hist_entry_callchain__fprintf(fp, self, total_samples);

return ret;
}

Expand Down Expand Up @@ -892,6 +941,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
.level = level,
.count = count,
.parent = NULL,
.sorted_chain = RB_ROOT
};
int cmp;

Expand Down Expand Up @@ -934,6 +984,8 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,

if (!cmp) {
he->count += count;
if (callchain)
append_chain(&he->callchain, chain);
return 0;
}

Expand All @@ -947,6 +999,10 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
if (!he)
return -ENOMEM;
*he = entry;
if (callchain) {
callchain_init(&he->callchain);
append_chain(&he->callchain, chain);
}
rb_link_node(&he->rb_node, parent, p);
rb_insert_color(&he->rb_node, &hist);

Expand Down Expand Up @@ -1023,6 +1079,9 @@ static void output__insert_entry(struct hist_entry *he)
struct rb_node *parent = NULL;
struct hist_entry *iter;

if (callchain)
sort_chain_to_rbtree(&he->sorted_chain, &he->callchain);

while (*p != NULL) {
parent = *p;
iter = rb_entry(parent, struct hist_entry, rb_node);
Expand Down Expand Up @@ -1599,6 +1658,7 @@ static const struct option options[] = {
"regex filter to identify parent, see: '--sort parent'"),
OPT_BOOLEAN('x', "exclude-other", &exclude_other,
"Only display entries with parent-match"),
OPT_BOOLEAN('c', "callchain", &callchain, "Display callchains"),
OPT_END()
};

Expand Down

0 comments on commit f55c555

Please sign in to comment.