From patchwork Tue Nov 17 22:37:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lina Iyer X-Patchwork-Id: 7643431 Return-Path: X-Original-To: patchwork-linux-arm@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 4B21DBF90C for ; Tue, 17 Nov 2015 22:54:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 64C4C205B1 for ; Tue, 17 Nov 2015 22:54:51 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 26F90205C4 for ; Tue, 17 Nov 2015 22:54:50 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyp7M-0004zj-99; Tue, 17 Nov 2015 22:52:52 +0000 Received: from mail-pa0-x22b.google.com ([2607:f8b0:400e:c03::22b]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zyou8-0005cw-QZ for linux-arm-kernel@lists.infradead.org; Tue, 17 Nov 2015 22:39:16 +0000 Received: by pacdm15 with SMTP id dm15so22084275pac.3 for ; Tue, 17 Nov 2015 14:38:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vWZW5o0Skdf6PXWHZNitDM6duJCADwD7ysvec3cS1qA=; b=LQ7UDX/bzcqVv8o5U8Pxhq/JlRjR/izh10NcFyvQubtRpB9wABzJ0xfY8vpIyUftFm gd9mqimPk3mIYnTlWd4vuUUJiLvzMOELtV+eO3KuW1QNzFgL4vnaPL2uKAnTqSc6yuGm FXXVicXHL/2+vUM1bV1qqZ+jwj7e24n48/lWmrp+wsXNH8mBHHl2GGU8ez8O6kZT1jZl vK7gvpKiOXVkE8A3UoQRTUeo3NdeNEQcr51C/nux3KKKgBdoX9gdlEix1800IEvHBheh HtCxuwlWygO9YSucTzYYFU4PkMB9S59NGPwNGDcawYVPCUMrHjxVaJ/pOU/wZn8ko4KB uG6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vWZW5o0Skdf6PXWHZNitDM6duJCADwD7ysvec3cS1qA=; b=AMqL0jfqbnq7Wrv9urIxofGAKcLy7Qs5ysPqdRK2LNGflDj614azjNpSB4CQmGq67h 05CYDm17ogViSm9IPrgqHr5GBvDKEIgioHl8lUUEVnhcDiPc66BNzQ39yCLgRjP1ZH7O 4ZRRWUHZS3e4hQ0x+BAxYEThEcCdcrRevXrerd/GsF2LhPzNAQvVke0XZZpuhJz8k9En 7nrwEiuQiK2EUvtRmUj8oFl+Fc2sYHlZ04UGPno9fw7c7k3q93wfgcbVDyyT9XdiEsAz YqXGPfMO5G0q/luRL9aFtvh4uysvm0EaVIkvnNiI0ir54iy8hjbymgzItfc4bYUHFhXk tvIg== X-Gm-Message-State: ALoCoQkHM0mZdwEVo+9RPt75t5GLCew5H41AOi49m4yIQ/KXAXF7xADrQua1K3aAXsFGv/cl/iO5 X-Received: by 10.67.23.229 with SMTP id id5mr67540940pad.64.1447799934800; Tue, 17 Nov 2015 14:38:54 -0800 (PST) Received: from ubuntu.localdomain ([8.42.77.226]) by smtp.gmail.com with ESMTPSA id hy1sm14875199pbb.63.2015.11.17.14.38.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Nov 2015 14:38:53 -0800 (PST) From: Lina Iyer To: ulf.hansson@linaro.org, khilman@linaro.org, linux-pm@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH RFC 18/27] drivers: cpu-pd: Add PM Domain governor for CPUs Date: Tue, 17 Nov 2015 15:37:42 -0700 Message-Id: <1447799871-56374-19-git-send-email-lina.iyer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> References: <1447799871-56374-1-git-send-email-lina.iyer@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151117_143913_152326_3A7BFAAC X-CRM114-Status: GOOD ( 19.95 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: k.kozlowski@samsung.com, lorenzo.pieralisi@arm.com, ahaslam@baylibre.com, linux-arm-msm@vger.kernel.org, sboyd@codeaurora.org, msivasub@codeaurora.org, geert@linux-m68k.org, Lina Iyer , agross@codeaurora.org, mtitinger@baylibre.com MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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 A PM domain comprising of CPUs may be powered off when all the CPUs in the domain are powered down. Powering down a CPU domain is generally a expensive operation and therefore the power performance trade offs should be considered. The time between the last CPU powering down and the first CPU powering up in a domain, is the time available for the domain to sleep. Ideally, the sleep time of the domain should fulfill the residency requirement of the domains' idle state. To do this effectively, read the time before the wakeup of the cluster's CPUs and ensure that the domain's idle state sleep time guarantees the QoS requirements of each of the CPU, the PM QoS CPU_DMA_LATENCY and the state's residency. Signed-off-by: Lina Iyer --- drivers/base/power/cpu-pd.c | 83 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/cpu-pd.c b/drivers/base/power/cpu-pd.c index 617ce54..a00abc1 100644 --- a/drivers/base/power/cpu-pd.c +++ b/drivers/base/power/cpu-pd.c @@ -21,6 +21,7 @@ #include #include #include +#include #define CPU_PD_NAME_MAX 36 @@ -66,6 +67,86 @@ static void get_cpus_in_domain(struct generic_pm_domain *genpd, } } +static bool cpu_pd_down_ok(struct dev_pm_domain *pd) +{ + struct generic_pm_domain *genpd = pd_to_genpd(pd); + struct cpu_pm_domain *cpu_pd = to_cpu_pd(genpd); + int qos = pm_qos_request(PM_QOS_CPU_DMA_LATENCY); + u64 sleep_ns = ~0; + ktime_t earliest; + int cpu; + int i; + + /* Reset the last set genpd state, default to index 0 */ + genpd->state_idx = 0; + + /* We dont want to power down, if QoS is 0 */ + if (!qos) + return false; + + /* + * Find the sleep time for the cluster. + * The time between now and the first wake up of any CPU that + * are in this domain hierarchy is the time available for the + * domain to be idle. + */ + earliest.tv64 = KTIME_MAX; + for_each_cpu_and(cpu, cpu_pd->cpus, cpu_online_mask) { + struct device *cpu_dev = get_cpu_device(cpu); + struct gpd_timing_data *td; + + td = &dev_gpd_data(cpu_dev)->td; + + if (earliest.tv64 < td->next_wakeup.tv64) + earliest = td->next_wakeup; + } + + sleep_ns = ktime_to_ns(ktime_sub(earliest, ktime_get())); + if (sleep_ns <= 0) + return false; + + /* + * Find the deepest sleep state that satisfies the residency + * requirement and the QoS constraint + */ + for (i = genpd->state_count - 1; i > 0; i--) { + u64 state_sleep_ns; + + state_sleep_ns = genpd->states[i].power_off_latency_ns + + genpd->states[i].power_on_latency_ns + + genpd->states[i].residency_ns; + + /* + * If we cant sleep to save power in the state, move on + * to the next lower idle state. + */ + if (state_sleep_ns > sleep_ns) + continue; + + /* + * We also dont want to sleep more than we should to + * gaurantee QoS. + */ + if (state_sleep_ns < (qos * NSEC_PER_USEC)) + break; + } + + if (i >= 0) + genpd->state_idx = i; + + return (i >= 0) ? true : false; +} + +static bool cpu_stop_ok(struct device *dev) +{ + return true; +} + +struct dev_power_governor cpu_pd_gov = { + .power_down_ok = cpu_pd_down_ok, + .stop_ok = cpu_stop_ok, +}; + static int cpu_pd_power_off(struct generic_pm_domain *genpd) { struct cpu_pm_domain *pd = to_cpu_pd(genpd); @@ -183,7 +264,7 @@ int of_register_cpu_pm_domain(struct device_node *dn, /* Register the CPU genpd */ pr_debug("adding %s as CPU PM domain.\n", pd->genpd->name); - ret = of_pm_genpd_init(dn, pd->genpd, &simple_qos_governor, false); + ret = of_pm_genpd_init(dn, pd->genpd, &cpu_pd_gov, false); if (ret) { pr_err("Unable to initialize domain %s\n", dn->full_name); return ret;