Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1405565imu; Sat, 26 Jan 2019 02:06:05 -0800 (PST) X-Google-Smtp-Source: ALg8bN6j/7+B6PzfD+RiLCEUu/hvkFfLbPYfVaEnKzwWX4waSEpP5OjDTf2dnmWb79mSizWQPg7A X-Received: by 2002:a17:902:9f93:: with SMTP id g19mr14332294plq.195.1548497165655; Sat, 26 Jan 2019 02:06:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548497165; cv=none; d=google.com; s=arc-20160816; b=laVNWJCiv2bkuB+ZN13RmNPUBt8XsUnR7sfA1J9pfNuqJfUfA8zZUKq3KCs89iB77A nqpS1V8frSJ9DWqqCR1VUIXkqXVzB1GLNW1w0j0k1XHvJZtk2KQZQO/SfCiX9A6bjgh7 2XZyjHPdezMN7u12C7XMUI5rPAx20fRa691u54p3PQ25ElHmjeX3K8aHz7iBxMCPdRjG Br9heZ0CMwR5SH+mPTWUh8QNn0F3ZWHUHpIQqLxWiNkv1cQCXfZ+7csbqmtzZTXll7va DVX6lQ/GEErgC2vNHs/Pap07u2ZD//ZmKOn7Kh3QnWctcVYVudltI5jhBCPfBHlY8A+G zVow== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date; bh=YwDJLCmJQxBuD6d0bxDY9YgbOlGUQ0uSmHIrf2Ij8Ik=; b=czF8cV6x9I/vEOQ9AxErf/DXziEyIv7hJ6HzJm+hW+SPwzlbNSf8ZNMHMr/G/B6w8x yJ6hyd1461B1JdJwNTT+BZcT1+qumdZryL/QYXmuGpv0MolESc3odUG8EB3HDkYVRvc8 jhjgxXuOA2DsS/psrDb71A6gZ5jj/xLBdmtU6apRagX+4hjUdiM76KcJ9PU7G8wkUQi9 9HRNzaoztvDC2/XHTDzVIzQpQcKIbWFZDS8HrbVLQU8ZYd8BGf+5YgiEdAN+bSsbhx/Y ph9rZM1/hJmc6pJu/QDtKxguVT0oTOVwq9OdYVGKeLxAindbxugywf/xy52NNuFhp4Yg /L/A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r18si9266067pgu.552.2019.01.26.02.05.50; Sat, 26 Jan 2019 02:06:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729594AbfAZKFR (ORCPT + 99 others); Sat, 26 Jan 2019 05:05:17 -0500 Received: from terminus.zytor.com ([198.137.202.136]:39527 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726143AbfAZKFR (ORCPT ); Sat, 26 Jan 2019 05:05:17 -0500 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTPS id x0QA56pt512958 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Sat, 26 Jan 2019 02:05:06 -0800 Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id x0QA5543512953; Sat, 26 Jan 2019 02:05:05 -0800 Date: Sat, 26 Jan 2019 02:05:05 -0800 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Davidlohr Bueso Message-ID: Cc: dave@stgolabs.net, acme@redhat.com, namhyung@kernel.org, tglx@linutronix.de, jolsa@kernel.org, linux-kernel@vger.kernel.org, hpa@zytor.com, mingo@kernel.org, dbueso@suse.de Reply-To: namhyung@kernel.org, acme@redhat.com, dave@stgolabs.net, tglx@linutronix.de, jolsa@kernel.org, hpa@zytor.com, linux-kernel@vger.kernel.org, mingo@kernel.org, dbueso@suse.de In-Reply-To: <20181206191819.30182-8-dave@stgolabs.net> References: <20181206191819.30182-8-dave@stgolabs.net> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf sched: Use cached rbtrees Git-Commit-ID: cb4c13a5137766c3666ae106e1a5549316992379 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 X-Spam-Status: No, score=-0.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, DATE_IN_FUTURE_24_48 autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: cb4c13a5137766c3666ae106e1a5549316992379 Gitweb: https://git.kernel.org/tip/cb4c13a5137766c3666ae106e1a5549316992379 Author: Davidlohr Bueso AuthorDate: Thu, 6 Dec 2018 11:18:19 -0800 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 25 Jan 2019 15:12:10 +0100 perf sched: Use cached rbtrees At the cost of an extra pointer, we can avoid the O(logN) cost of finding the first element in the tree (smallest node), which is something heavily required for perf-sched. Signed-off-by: Davidlohr Bueso Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/r/20181206191819.30182-8-dave@stgolabs.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 2e0f0c65964a..640558e9352e 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -213,7 +213,7 @@ struct perf_sched { u64 all_runtime; u64 all_count; u64 cpu_last_switched[MAX_CPUS]; - struct rb_root atom_root, sorted_atom_root, merged_atom_root; + struct rb_root_cached atom_root, sorted_atom_root, merged_atom_root; struct list_head sort_list, cmp_pid; bool force; bool skip_merge; @@ -271,7 +271,7 @@ struct evsel_runtime { struct idle_thread_runtime { struct thread_runtime tr; struct thread *last_thread; - struct rb_root sorted_root; + struct rb_root_cached sorted_root; struct callchain_root callchain; struct callchain_cursor cursor; }; @@ -950,10 +950,10 @@ thread_lat_cmp(struct list_head *list, struct work_atoms *l, struct work_atoms * } static struct work_atoms * -thread_atoms_search(struct rb_root *root, struct thread *thread, +thread_atoms_search(struct rb_root_cached *root, struct thread *thread, struct list_head *sort_list) { - struct rb_node *node = root->rb_node; + struct rb_node *node = root->rb_root.rb_node; struct work_atoms key = { .thread = thread }; while (node) { @@ -976,10 +976,11 @@ thread_atoms_search(struct rb_root *root, struct thread *thread, } static void -__thread_latency_insert(struct rb_root *root, struct work_atoms *data, +__thread_latency_insert(struct rb_root_cached *root, struct work_atoms *data, struct list_head *sort_list) { - struct rb_node **new = &(root->rb_node), *parent = NULL; + struct rb_node **new = &(root->rb_root.rb_node), *parent = NULL; + bool leftmost = true; while (*new) { struct work_atoms *this; @@ -992,12 +993,14 @@ __thread_latency_insert(struct rb_root *root, struct work_atoms *data, if (cmp > 0) new = &((*new)->rb_left); - else + else { new = &((*new)->rb_right); + leftmost = false; + } } rb_link_node(&data->node, parent, new); - rb_insert_color(&data->node, root); + rb_insert_color_cached(&data->node, root, leftmost); } static int thread_atoms_insert(struct perf_sched *sched, struct thread *thread) @@ -1447,15 +1450,15 @@ static int sort_dimension__add(const char *tok, struct list_head *list) static void perf_sched__sort_lat(struct perf_sched *sched) { struct rb_node *node; - struct rb_root *root = &sched->atom_root; + struct rb_root_cached *root = &sched->atom_root; again: for (;;) { struct work_atoms *data; - node = rb_first(root); + node = rb_first_cached(root); if (!node) break; - rb_erase(node, root); + rb_erase_cached(node, root); data = rb_entry(node, struct work_atoms, node); __thread_latency_insert(&sched->sorted_atom_root, data, &sched->sort_list); } @@ -2762,12 +2765,12 @@ static size_t callchain__fprintf_folded(FILE *fp, struct callchain_node *node) return ret; } -static size_t timehist_print_idlehist_callchain(struct rb_root *root) +static size_t timehist_print_idlehist_callchain(struct rb_root_cached *root) { size_t ret = 0; FILE *fp = stdout; struct callchain_node *chain; - struct rb_node *rb_node = rb_first(root); + struct rb_node *rb_node = rb_first_cached(root); printf(" %16s %8s %s\n", "Idle time (msec)", "Count", "Callchains"); printf(" %.16s %.8s %.50s\n", graph_dotted_line, graph_dotted_line, @@ -2868,7 +2871,7 @@ static void timehist_print_summary(struct perf_sched *sched, if (itr == NULL) continue; - callchain_param.sort(&itr->sorted_root, &itr->callchain, + callchain_param.sort(&itr->sorted_root.rb_root, &itr->callchain, 0, &callchain_param); printf(" CPU %2d:", i); @@ -3074,11 +3077,12 @@ static void print_bad_events(struct perf_sched *sched) } } -static void __merge_work_atoms(struct rb_root *root, struct work_atoms *data) +static void __merge_work_atoms(struct rb_root_cached *root, struct work_atoms *data) { - struct rb_node **new = &(root->rb_node), *parent = NULL; + struct rb_node **new = &(root->rb_root.rb_node), *parent = NULL; struct work_atoms *this; const char *comm = thread__comm_str(data->thread), *this_comm; + bool leftmost = true; while (*new) { int cmp; @@ -3092,6 +3096,7 @@ static void __merge_work_atoms(struct rb_root *root, struct work_atoms *data) new = &((*new)->rb_left); } else if (cmp < 0) { new = &((*new)->rb_right); + leftmost = false; } else { this->num_merged++; this->total_runtime += data->total_runtime; @@ -3109,7 +3114,7 @@ static void __merge_work_atoms(struct rb_root *root, struct work_atoms *data) data->num_merged++; rb_link_node(&data->node, parent, new); - rb_insert_color(&data->node, root); + rb_insert_color_cached(&data->node, root, leftmost); } static void perf_sched__merge_lat(struct perf_sched *sched) @@ -3120,8 +3125,8 @@ static void perf_sched__merge_lat(struct perf_sched *sched) if (sched->skip_merge) return; - while ((node = rb_first(&sched->atom_root))) { - rb_erase(node, &sched->atom_root); + while ((node = rb_first_cached(&sched->atom_root))) { + rb_erase_cached(node, &sched->atom_root); data = rb_entry(node, struct work_atoms, node); __merge_work_atoms(&sched->merged_atom_root, data); } @@ -3143,7 +3148,7 @@ static int perf_sched__lat(struct perf_sched *sched) printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n"); printf(" -----------------------------------------------------------------------------------------------------------------\n"); - next = rb_first(&sched->sorted_atom_root); + next = rb_first_cached(&sched->sorted_atom_root); while (next) { struct work_atoms *work_list;