aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2012-09-11 01:13:04 -0400
committerJiri Olsa <jolsa@kernel.org>2014-06-01 08:34:57 -0400
commit7a13aa28aa268359cee006059731f49bcd1f839e (patch)
treed3748f0fa3e62fabf3f018cd2789076dc593f392 /tools
parenta0b51af367a6831330564c96dc4cc1ac63413701 (diff)
perf hists: Accumulate hist entry stat based on the callchain
Call __hists__add_entry() for each callchain node to get an accumulated stat for an entry. Introduce new cumulative_iter ops to process them properly. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Tested-by: Arun Sharma <asharma@fb.com> Tested-by: Rodrigo Campos <rodrigo@sdfg.com.ar> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1401335910-16832-6-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/util/callchain.c3
-rw-r--r--tools/perf/util/hist.c96
-rw-r--r--tools/perf/util/hist.h1
4 files changed, 101 insertions, 1 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 3201bdfa8c3f..e8fa9fea341f 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -115,6 +115,8 @@ static int process_sample_event(struct perf_tool *tool,
115 iter.ops = &hist_iter_branch; 115 iter.ops = &hist_iter_branch;
116 else if (rep->mem_mode) 116 else if (rep->mem_mode)
117 iter.ops = &hist_iter_mem; 117 iter.ops = &hist_iter_mem;
118 else if (symbol_conf.cumulate_callchain)
119 iter.ops = &hist_iter_cumulative;
118 else 120 else
119 iter.ops = &hist_iter_normal; 121 iter.ops = &hist_iter_normal;
120 122
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 9a42382b3921..2af69c47b725 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -616,7 +616,8 @@ int sample__resolve_callchain(struct perf_sample *sample, struct symbol **parent
616 if (sample->callchain == NULL) 616 if (sample->callchain == NULL)
617 return 0; 617 return 0;
618 618
619 if (symbol_conf.use_callchain || sort__has_parent) { 619 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain ||
620 sort__has_parent) {
620 return machine__resolve_callchain(al->machine, evsel, al->thread, 621 return machine__resolve_callchain(al->machine, evsel, al->thread,
621 sample, parent, al, max_stack); 622 sample, parent, al, max_stack);
622 } 623 }
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index b9facf33b224..6079b5acfb6d 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -696,6 +696,94 @@ iter_finish_normal_entry(struct hist_entry_iter *iter, struct addr_location *al)
696 return hist_entry__append_callchain(he, sample); 696 return hist_entry__append_callchain(he, sample);
697} 697}
698 698
699static int
700iter_prepare_cumulative_entry(struct hist_entry_iter *iter __maybe_unused,
701 struct addr_location *al __maybe_unused)
702{
703 callchain_cursor_commit(&callchain_cursor);
704 return 0;
705}
706
707static int
708iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
709 struct addr_location *al)
710{
711 struct perf_evsel *evsel = iter->evsel;
712 struct perf_sample *sample = iter->sample;
713 struct hist_entry *he;
714 int err = 0;
715
716 he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
717 sample->period, sample->weight,
718 sample->transaction, true);
719 if (he == NULL)
720 return -ENOMEM;
721
722 iter->he = he;
723
724 /*
725 * The iter->he will be over-written after ->add_next_entry()
726 * called so inc stats for the original entry now.
727 */
728 if (ui__has_annotation())
729 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
730
731 hists__inc_nr_samples(&evsel->hists, he->filtered);
732
733 return err;
734}
735
736static int
737iter_next_cumulative_entry(struct hist_entry_iter *iter,
738 struct addr_location *al)
739{
740 struct callchain_cursor_node *node;
741
742 node = callchain_cursor_current(&callchain_cursor);
743 if (node == NULL)
744 return 0;
745
746 al->map = node->map;
747 al->sym = node->sym;
748 if (node->map)
749 al->addr = node->map->map_ip(node->map, node->ip);
750 else
751 al->addr = node->ip;
752
753 if (iter->hide_unresolved && al->sym == NULL)
754 return 0;
755
756 callchain_cursor_advance(&callchain_cursor);
757 return 1;
758}
759
760static int
761iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
762 struct addr_location *al)
763{
764 struct perf_evsel *evsel = iter->evsel;
765 struct perf_sample *sample = iter->sample;
766 struct hist_entry *he;
767
768 he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
769 sample->period, sample->weight,
770 sample->transaction, false);
771 if (he == NULL)
772 return -ENOMEM;
773
774 iter->he = he;
775
776 return 0;
777}
778
779static int
780iter_finish_cumulative_entry(struct hist_entry_iter *iter,
781 struct addr_location *al __maybe_unused)
782{
783 iter->he = NULL;
784 return 0;
785}
786
699const struct hist_iter_ops hist_iter_mem = { 787const struct hist_iter_ops hist_iter_mem = {
700 .prepare_entry = iter_prepare_mem_entry, 788 .prepare_entry = iter_prepare_mem_entry,
701 .add_single_entry = iter_add_single_mem_entry, 789 .add_single_entry = iter_add_single_mem_entry,
@@ -720,6 +808,14 @@ const struct hist_iter_ops hist_iter_normal = {
720 .finish_entry = iter_finish_normal_entry, 808 .finish_entry = iter_finish_normal_entry,
721}; 809};
722 810
811const struct hist_iter_ops hist_iter_cumulative = {
812 .prepare_entry = iter_prepare_cumulative_entry,
813 .add_single_entry = iter_add_single_cumulative_entry,
814 .next_entry = iter_next_cumulative_entry,
815 .add_next_entry = iter_add_next_cumulative_entry,
816 .finish_entry = iter_finish_cumulative_entry,
817};
818
723int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al, 819int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
724 struct perf_evsel *evsel, struct perf_sample *sample, 820 struct perf_evsel *evsel, struct perf_sample *sample,
725 int max_stack_depth) 821 int max_stack_depth)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index bedb24d3643c..78409f95d012 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -124,6 +124,7 @@ struct hist_entry_iter {
124extern const struct hist_iter_ops hist_iter_normal; 124extern const struct hist_iter_ops hist_iter_normal;
125extern const struct hist_iter_ops hist_iter_branch; 125extern const struct hist_iter_ops hist_iter_branch;
126extern const struct hist_iter_ops hist_iter_mem; 126extern const struct hist_iter_ops hist_iter_mem;
127extern const struct hist_iter_ops hist_iter_cumulative;
127 128
128struct hist_entry *__hists__add_entry(struct hists *hists, 129struct hist_entry *__hists__add_entry(struct hists *hists,
129 struct addr_location *al, 130 struct addr_location *al,