perf top: Decay periods in callchains
authorNamhyung Kim <namhyung@kernel.org>
Tue, 5 Jan 2016 03:06:00 +0000 (12:06 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Fri, 8 Jan 2016 15:37:51 +0000 (12:37 -0300)
It missed to decay periods in callchains when decaying hist entries.
This resulted in more than 100 percent overhead in callchains in the
fractal style output.

Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1451963160-17196-1-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/hist.c

index 564377d2bebf3ee1c11d26839f68e42d7ad6b62f..53c43eb9489e4ba4a4e56a795bc05c2b85fb4cbc 100644 (file)
@@ -925,6 +925,34 @@ void free_callchain(struct callchain_root *root)
        free_callchain_node(&root->node);
 }
 
+static u64 decay_callchain_node(struct callchain_node *node)
+{
+       struct callchain_node *child;
+       struct rb_node *n;
+       u64 child_hits = 0;
+
+       n = rb_first(&node->rb_root_in);
+       while (n) {
+               child = container_of(n, struct callchain_node, rb_node_in);
+
+               child_hits += decay_callchain_node(child);
+               n = rb_next(n);
+       }
+
+       node->hit = (node->hit * 7) / 8;
+       node->children_hit = child_hits;
+
+       return node->hit;
+}
+
+void decay_callchain(struct callchain_root *root)
+{
+       if (!symbol_conf.use_callchain)
+               return;
+
+       decay_callchain_node(&root->node);
+}
+
 int callchain_node__make_parent_list(struct callchain_node *node)
 {
        struct callchain_node *parent = node->parent;
index 8ac8f043004c792c4f265049ec85c1fcc4c3225a..18dd22269764cfe29e34964e02f70b5d1f77831d 100644 (file)
@@ -253,6 +253,7 @@ int callchain_node__fprintf_value(struct callchain_node *node,
                                  FILE *fp, u64 total);
 
 void free_callchain(struct callchain_root *root);
+void decay_callchain(struct callchain_root *root);
 int callchain_node__make_parent_list(struct callchain_node *node);
 
 #endif /* __PERF_CALLCHAIN_H */
index afc9b8f1b36cac095cc068232ae81be78c0e767b..888776b43cb0ec8777f1711e229d467febb5bdac 100644 (file)
@@ -254,6 +254,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
        he_stat__decay(&he->stat);
        if (symbol_conf.cumulate_callchain)
                he_stat__decay(he->stat_acc);
+       decay_callchain(he->callchain);
 
        diff = prev_period - he->stat.period;