From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965228AbcCKIvQ (ORCPT ); Fri, 11 Mar 2016 03:51:16 -0500 Received: from torg.zytor.com ([198.137.202.12]:33506 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S964895AbcCKIvC (ORCPT ); Fri, 11 Mar 2016 03:51:02 -0500 Date: Fri, 11 Mar 2016 00:50:24 -0800 From: tip-bot for Namhyung Kim Message-ID: Cc: hpa@zytor.com, dsahern@gmail.com, linux-kernel@vger.kernel.org, eranian@google.com, peterz@infradead.org, andi@firstfloor.org, tglx@linutronix.de, namhyung@kernel.org, jolsa@kernel.org, mingo@kernel.org, acme@redhat.com, wangnan0@huawei.com Reply-To: peterz@infradead.org, andi@firstfloor.org, tglx@linutronix.de, dsahern@gmail.com, hpa@zytor.com, linux-kernel@vger.kernel.org, eranian@google.com, mingo@kernel.org, acme@redhat.com, wangnan0@huawei.com, jolsa@kernel.org, namhyung@kernel.org In-Reply-To: <1457531222-18130-8-git-send-email-namhyung@kernel.org> References: <1457531222-18130-8-git-send-email-namhyung@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf tools: Recalc total periods using top-level entries in hierarchy Git-Commit-ID: f7fb538afea55383a9383dac5c56887c601af5f4 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: f7fb538afea55383a9383dac5c56887c601af5f4 Gitweb: http://git.kernel.org/tip/f7fb538afea55383a9383dac5c56887c601af5f4 Author: Namhyung Kim AuthorDate: Wed, 9 Mar 2016 22:47:02 +0900 Committer: Arnaldo Carvalho de Melo CommitDate: Thu, 10 Mar 2016 16:46:13 -0300 perf tools: Recalc total periods using top-level entries in hierarchy When hierarchy mode is enabled, each entry in a hierarchy level shares the period. IOW an upper level entry's period is the sum of lower level entries. Thus perf uses only one of them to calculate the total period of hists. It was lowest-level (leaf) entries but it has a problem when it comes to filters. If a filter is applied, entries in the same level will be filtered or not. But upper level entries still have period of their sum including filtered one. So total sum of upper level entries will not be same as sum of lower level entries. This resulted in entries having more than 100% of overhead and it can be produced using perf top with filter(s). Reported-and-Tested-by: Jiri Olsa Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Wang Nan Link: http://lkml.kernel.org/r/1457531222-18130-8-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index a98f934..290b3cb 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1453,6 +1453,31 @@ void hists__inc_stats(struct hists *hists, struct hist_entry *h) hists->stats.total_period += h->stat.period; } +static void hierarchy_recalc_total_periods(struct hists *hists) +{ + struct rb_node *node; + struct hist_entry *he; + + node = rb_first(&hists->entries); + + hists->stats.total_period = 0; + hists->stats.total_non_filtered_period = 0; + + /* + * recalculate total period using top-level entries only + * since lower level entries only see non-filtered entries + * but upper level entries have sum of both entries. + */ + while (node) { + he = rb_entry(node, struct hist_entry, rb_node); + node = rb_next(node); + + hists->stats.total_period += he->stat.period; + if (!he->filtered) + hists->stats.total_non_filtered_period += he->stat.period; + } +} + static void hierarchy_insert_output_entry(struct rb_root *root, struct hist_entry *he) { @@ -1518,11 +1543,6 @@ static void hists__hierarchy_output_resort(struct hists *hists, continue; } - /* only update stat for leaf entries to avoid duplication */ - hists__inc_stats(hists, he); - if (!he->filtered) - hists__calc_col_len(hists, he); - if (!use_callchain) continue; @@ -1602,11 +1622,13 @@ static void output_resort(struct hists *hists, struct ui_progress *prog, hists__reset_col_len(hists); if (symbol_conf.report_hierarchy) { - return hists__hierarchy_output_resort(hists, prog, - &hists->entries_collapsed, - &hists->entries, - min_callchain_hits, - use_callchain); + hists__hierarchy_output_resort(hists, prog, + &hists->entries_collapsed, + &hists->entries, + min_callchain_hits, + use_callchain); + hierarchy_recalc_total_periods(hists); + return; } if (sort__need_collapse) @@ -1927,6 +1949,8 @@ static void hists__filter_hierarchy(struct hists *hists, int type, const void *a } } + hierarchy_recalc_total_periods(hists); + /* * resort output after applying a new filter since filter in a lower * hierarchy can change periods in a upper hierarchy.