From patchwork Thu Jun 8 07:55:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dietmar Eggemann X-Patchwork-Id: 103338 Delivered-To: patch@linaro.org Received: by 10.182.29.35 with SMTP id g3csp2123658obh; Thu, 8 Jun 2017 00:55:51 -0700 (PDT) X-Received: by 10.84.231.136 with SMTP id g8mr33892029plk.257.1496908551855; Thu, 08 Jun 2017 00:55:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1496908551; cv=none; d=google.com; s=arc-20160816; b=oSdgJ7Lw8oOBRwE5ErUnxiUH9rFVc7vY8Fta99RtIxe629rp8SVl+gEndNWKL2i1Mf keDzLYse65xin/AUA3wpWHGRvEB+KHuw/7zdMYm4VC8zjIvOt4N62bmtYSx1jv0RkuS2 SufjIDxfzD0KTk+TVIwLQt9dg4vKL9JGae5L5J33ySm7V4t0FzYA1CdgqeksZAZfZoPH 4qX5yxK5oQgmaD8AkiFqN58a/VnHuRT4fDCL9nkPihkp9V/7YwZ9brGXFlHjCNYqAP+9 mzkjDCmYwaWHs3UDC/5Vy9xOdVjKE5lszR24i5a65ESexo5cz28ZESFi+jMdrrDePLbX stnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=8GEACDALr7r8V3bnlmbe8m0/ebRDrjsiye74tv4P1ds=; b=okM4lXkb35AYMMEUM5I3PvJyhLMApUjqM39cDdDCzw3UXhTPLB0lG2eSwI4gVCWZYY YO2tni21VrC/wEm9si5GK5VrA7v0M33LpjNlNshHT6sBWXTuWTokTZ3R4aPL7qHpk9ht NTDsTnBS1Yy9U35qagCpGmOFH+nM55sd+07C+cFlXibs9nldmNYa53Nt81uqh5ts5n4o Yl/31rAMGm43cIFAzRGuD5e9H6JBtald8XKzfxzhIZouEzIhE87oEUMD7cFkSpVtAnjz XmTiX3g5zOwN9ZV0cX5oIH3/iFPsgEx/XGrMzNoTFQyMPCgtBbdxAieqa3+1LEOa4l9f Hvrg== 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 h126si3781772pgc.62.2017.06.08.00.55.51; Thu, 08 Jun 2017 00:55:51 -0700 (PDT) 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 S1751923AbdFHHzq (ORCPT + 25 others); Thu, 8 Jun 2017 03:55:46 -0400 Received: from foss.arm.com ([217.140.101.70]:43226 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751619AbdFHHzo (ORCPT ); Thu, 8 Jun 2017 03:55:44 -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 7D3A3164F; Thu, 8 Jun 2017 00:55:38 -0700 (PDT) Received: from e107985-lin.cambridge.arm.com (e107985-lin.cambridge.arm.com [10.1.210.41]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8231B3F3E1; Thu, 8 Jun 2017 00:55:36 -0700 (PDT) From: Dietmar Eggemann To: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org, linux@arm.linux.org.uk, linux-arm-kernel@lists.infradead.org, Greg Kroah-Hartman , Russell King , Catalin Marinas , Will Deacon , Juri Lelli , Vincent Guittot , Peter Zijlstra , Morten Rasmussen Subject: [PATCH 2/6] drivers base/arch_topology: frequency-invariant load-tracking support Date: Thu, 8 Jun 2017 08:55:09 +0100 Message-Id: <20170608075513.12475-3-dietmar.eggemann@arm.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170608075513.12475-1-dietmar.eggemann@arm.com> References: <20170608075513.12475-1-dietmar.eggemann@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Implements an arch-specific frequency-scaling function topology_get_freq_scale() which provides the following frequency scaling factor: current_freq(cpu) << SCHED_CAPACITY_SHIFT / max_supported_freq(cpu) The debug output in init_cpu_capacity_callback() has been changed to be able to distinguish whether cpu capacity and max frequency or only max frequency has been set. The latter case happens on systems where there is no or broken cpu capacity binding (cpu node property capacity-dmips-mhz) information. One possible consumer of this is the Per-Entity Load Tracking (PELT) mechanism of the task scheduler. Cc: Catalin Marinas Cc: Will Deacon Cc: Russell King Cc: Greg Kroah-Hartman Cc: Juri Lelli Signed-off-by: Dietmar Eggemann --- drivers/base/arch_topology.c | 52 ++++++++++++++++++++++++++++++++++++++++--- include/linux/arch_topology.h | 2 ++ 2 files changed, 51 insertions(+), 3 deletions(-) -- 2.11.0 diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index 272831c89feb..f6f14670bdab 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -24,12 +24,18 @@ static DEFINE_MUTEX(cpu_scale_mutex); static DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE; +static DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE; unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu) { return per_cpu(cpu_scale, cpu); } +unsigned long topology_get_freq_scale(struct sched_domain *sd, int cpu) +{ + return per_cpu(freq_scale, cpu); +} + void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity) { per_cpu(cpu_scale, cpu) = capacity; @@ -164,6 +170,7 @@ static cpumask_var_t cpus_to_visit; static bool cap_parsing_done; static void parsing_done_workfn(struct work_struct *work); static DECLARE_WORK(parsing_done_work, parsing_done_workfn); +static DEFINE_PER_CPU(unsigned long, max_freq); static int init_cpu_capacity_callback(struct notifier_block *nb, @@ -185,6 +192,7 @@ init_cpu_capacity_callback(struct notifier_block *nb, cpus_to_visit, policy->related_cpus); for_each_cpu(cpu, policy->related_cpus) { + per_cpu(max_freq, cpu) = policy->cpuinfo.max_freq; if (cap_parsing_failed) continue; raw_capacity[cpu] = topology_get_cpu_scale(NULL, cpu) * @@ -195,8 +203,10 @@ init_cpu_capacity_callback(struct notifier_block *nb, if (!cap_parsing_failed) { topology_normalize_cpu_scale(); kfree(raw_capacity); + pr_debug("cpu_capacity: parsing done\n"); + } else { + pr_debug("cpu_capacity: max frequency parsing done\n"); } - pr_debug("cpu_capacity: parsing done\n"); cap_parsing_done = true; schedule_work(&parsing_done_work); } @@ -208,8 +218,38 @@ static struct notifier_block init_cpu_capacity_notifier = { .notifier_call = init_cpu_capacity_callback, }; +static void set_freq_scale(unsigned int cpu, unsigned long freq) +{ + unsigned long max = per_cpu(max_freq, cpu); + + if (!max) + return; + + per_cpu(freq_scale, cpu) = (freq << SCHED_CAPACITY_SHIFT) / max; +} + +static int set_freq_scale_callback(struct notifier_block *nb, + unsigned long val, + void *data) +{ + struct cpufreq_freqs *freq = data; + + switch (val) { + case CPUFREQ_PRECHANGE: + set_freq_scale(freq->cpu, freq->new); + } + + return 0; +} + +static struct notifier_block set_freq_scale_notifier = { + .notifier_call = set_freq_scale_callback, +}; + static int __init register_cpufreq_notifier(void) { + int ret; + /* * on ACPI-based systems we need to use the default cpu capacity * until we have the necessary code to parse the cpu capacity, so @@ -225,8 +265,14 @@ static int __init register_cpufreq_notifier(void) cpumask_copy(cpus_to_visit, cpu_possible_mask); - return cpufreq_register_notifier(&init_cpu_capacity_notifier, - CPUFREQ_POLICY_NOTIFIER); + ret = cpufreq_register_notifier(&init_cpu_capacity_notifier, + CPUFREQ_POLICY_NOTIFIER); + + if (ret) + return ret; + + return cpufreq_register_notifier(&set_freq_scale_notifier, + CPUFREQ_TRANSITION_NOTIFIER); } core_initcall(register_cpufreq_notifier); diff --git a/include/linux/arch_topology.h b/include/linux/arch_topology.h index 9af3c174c03a..3fb4d8ccb179 100644 --- a/include/linux/arch_topology.h +++ b/include/linux/arch_topology.h @@ -12,6 +12,8 @@ int topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu); struct sched_domain; unsigned long topology_get_cpu_scale(struct sched_domain *sd, int cpu); +unsigned long topology_get_freq_scale(struct sched_domain *sd, int cpu); + void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity); #endif /* _LINUX_ARCH_TOPOLOGY_H_ */