From patchwork Tue Jul 7 18:24:11 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Morten Rasmussen X-Patchwork-Id: 6738391 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2F366C05AC for ; Tue, 7 Jul 2015 18:59:58 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 46EC920626 for ; Tue, 7 Jul 2015 18:59:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 62AE320763 for ; Tue, 7 Jul 2015 18:59:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933230AbbGGS7f (ORCPT ); Tue, 7 Jul 2015 14:59:35 -0400 Received: from foss.arm.com ([217.140.101.70]:37591 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932905AbbGGSXL (ORCPT ); Tue, 7 Jul 2015 14:23:11 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 6B6C4390; Tue, 7 Jul 2015 11:23:38 -0700 (PDT) Received: from e105550-lin.cambridge.arm.com (e105550-lin.cambridge.arm.com [10.2.131.193]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 5915A3F23A; Tue, 7 Jul 2015 11:23:09 -0700 (PDT) From: Morten Rasmussen To: peterz@infradead.org, mingo@redhat.com Cc: vincent.guittot@linaro.org, daniel.lezcano@linaro.org, Dietmar Eggemann , yuyang.du@intel.com, mturquette@baylibre.com, rjw@rjwysocki.net, Juri Lelli , sgurrappadi@nvidia.com, pang.xunlei@zte.com.cn, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Subject: [RFCv5 PATCH 28/46] sched: Count number of shallower idle-states in struct sched_group_energy Date: Tue, 7 Jul 2015 19:24:11 +0100 Message-Id: <1436293469-25707-29-git-send-email-morten.rasmussen@arm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1436293469-25707-1-git-send-email-morten.rasmussen@arm.com> References: <1436293469-25707-1-git-send-email-morten.rasmussen@arm.com> Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-7.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP cpuidle associates all idle-states with each cpu while the energy model associates them with the sched_group covering the cpus coordinating entry to the idle-state. To look up the idle-state power consumption in the energy model it is therefore necessary to translate from cpuidle idle-state index to energy model index. For this purpose it is helpful to know how many idle-states that are listed in lower level sched_groups (in struct sched_group_energy). Example: ARMv8 big.LITTLE JUNO (Cortex A57, A53) idle-states: Idle-state cpuidle Energy model table indices index per-cpu sg per-cluster sg WFI 0 0 (0) Core power-down 1 1 0* Cluster power-down 2 (1) 1 For per-cpu sgs no translation is required. If cpuidle reports state index 0 or 1, the cpu is in WFI or core power-down, respectively. We can look the idle-power up directly in the sg energy model table. Idle-state cluster power-down, is represented in the per-cluster sg energy model table as index 1. Index 0* is reserved for cluster power consumption when the cpus all are in state 0 or 1, but cpuidle decided not to go for cluster power-down. Given the index from cpuidle we can compute the correct index in the energy model tables for the sgs at each level if we know how many states are in the tables in the child sgs. The actual translation is implemented in a later patch. cc: Ingo Molnar cc: Peter Zijlstra Signed-off-by: Morten Rasmussen --- include/linux/sched.h | 1 + kernel/sched/core.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/linux/sched.h b/include/linux/sched.h index 8ac2db8..6b5e44d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1031,6 +1031,7 @@ struct sched_group_energy { atomic_t ref; unsigned int nr_idle_states; /* number of idle states */ struct idle_state *idle_states; /* ptr to idle state array */ + unsigned int nr_idle_states_below; /* number idle states in lower groups */ unsigned int nr_cap_states; /* number of capacity states */ struct capacity_state *cap_states; /* ptr to capacity state array */ }; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index fe4b361..c13fa9c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -6117,6 +6117,7 @@ static void init_sched_energy(int cpu, struct sched_domain *sd, struct sched_group_energy *sge = sg->sge; sched_domain_energy_f fn = tl->energy; struct cpumask *mask = sched_group_cpus(sg); + int nr_idle_states_below = 0; if (fn && sd->child && !sd->child->groups->sge) { pr_err("BUG: EAS setup broken for CPU%d\n", cpu); @@ -6140,7 +6141,18 @@ static void init_sched_energy(int cpu, struct sched_domain *sd, if (cpumask_weight(mask) > 1) check_sched_energy_data(cpu, fn, mask); + /* Figure out the number of true cpuidle states below current group */ + sd = sd->child; + for_each_lower_domain(sd) { + nr_idle_states_below += sd->groups->sge->nr_idle_states; + + /* Disregard non-cpuidle 'active' idle states */ + if (sd->child) + nr_idle_states_below--; + } + sge->nr_idle_states = fn(cpu)->nr_idle_states; + sge->nr_idle_states_below = nr_idle_states_below; sge->nr_cap_states = fn(cpu)->nr_cap_states; sge->idle_states = (struct idle_state *) ((void *)&sge->cap_states +