From patchwork Wed Oct 8 06:26:12 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Turquette X-Patchwork-Id: 38455 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f71.google.com (mail-wg0-f71.google.com [74.125.82.71]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4E9F620D4A for ; Wed, 8 Oct 2014 06:26:43 +0000 (UTC) Received: by mail-wg0-f71.google.com with SMTP id y10sf4813798wgg.2 for ; Tue, 07 Oct 2014 23:26:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=QPCcsrI+GkhQ5z/z1BnuVeiMspTNh/wKjLa+3ViWpw0=; b=PIvFfPWhiOAK1871m8kXV8Q+u9iFfYkdh/ga/hcjOu5Fro65qWchtnCgYYauRYxzfO hyku6qRkhkACnRoBXrFjgDHSCZLtIVKLth8KH/vctuXYIUyFp2IOms3JSI6nJcF5Kfhn 8FSBbysp1jlRWRJStmlMtDmAg1Qev0U4KOoIyJVzqe1XOU5u5eSyxqjC0U3RJbdp//7d zgaEgL1Pks1Uu2sY38hFMv9rJTNijxIQ8UJWwAU5Tjj8bg8K9tXECYV0jvX6JnWOZIoa jkuOXhj6Ov6I8pZtYo2mZTE/KISE7DyzxZNijPr7cMz0yX/jP49RWsYmdKtssfdtSwrN 2NZA== X-Gm-Message-State: ALoCoQn0BfqZfcRgBdOR0e6yfFvAyXVgfnNqrxUT4ZYfUeHVePsEjxMLGpCRi8IsHcQ2Pi/Hmjp5 X-Received: by 10.181.25.234 with SMTP id it10mr1254396wid.1.1412749602500; Tue, 07 Oct 2014 23:26:42 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.8.199 with SMTP id t7ls24907laa.3.gmail; Tue, 07 Oct 2014 23:26:42 -0700 (PDT) X-Received: by 10.112.171.229 with SMTP id ax5mr8443711lbc.25.1412749602247; Tue, 07 Oct 2014 23:26:42 -0700 (PDT) Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com [209.85.217.172]) by mx.google.com with ESMTPS id ay3si31722803lbc.4.2014.10.07.23.26.42 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 07 Oct 2014 23:26:42 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) client-ip=209.85.217.172; Received: by mail-lb0-f172.google.com with SMTP id b6so7485436lbj.17 for ; Tue, 07 Oct 2014 23:26:42 -0700 (PDT) X-Received: by 10.112.4.33 with SMTP id h1mr8417930lbh.67.1412749602088; Tue, 07 Oct 2014 23:26:42 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.84.229 with SMTP id c5csp9341lbz; Tue, 7 Oct 2014 23:26:41 -0700 (PDT) X-Received: by 10.66.66.40 with SMTP id c8mr8387055pat.83.1412749600612; Tue, 07 Oct 2014 23:26:40 -0700 (PDT) Received: from mail-pd0-f169.google.com (mail-pd0-f169.google.com [209.85.192.169]) by mx.google.com with ESMTPS id w1si3927340pdc.105.2014.10.07.23.26.40 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 07 Oct 2014 23:26:40 -0700 (PDT) Received-SPF: pass (google.com: domain of mturquette@linaro.org designates 209.85.192.169 as permitted sender) client-ip=209.85.192.169; Received: by mail-pd0-f169.google.com with SMTP id w10so6368888pde.14 for ; Tue, 07 Oct 2014 23:26:39 -0700 (PDT) X-Received: by 10.66.163.33 with SMTP id yf1mr8032083pab.96.1412749599926; Tue, 07 Oct 2014 23:26:39 -0700 (PDT) Received: from quantum.home (pool-108-47-66-231.lsanca.fios.verizon.net. [108.47.66.231]) by mx.google.com with ESMTPSA id pl11sm15461691pdb.54.2014.10.07.23.26.38 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 07 Oct 2014 23:26:39 -0700 (PDT) From: Mike Turquette To: Morten Rasmussen , peterz@infradead.org, mingo@redhat.com Cc: dietmar.eggemann@arm.com, pjt@google.com, bsegall@google.com, vincent.guittot@linaro.org, nicolas.pitre@linaro.org, rjw@rjwysocki.net, linux-kernel@vger.kernel.org, tuukka.tikkanen@linaro.org, Mike Turquette Subject: [PATCH RFC 2/2] cpufreq: arm_big_little: provide cpu capacity Date: Tue, 7 Oct 2014 23:26:12 -0700 Message-Id: <1412749572-29449-3-git-send-email-mturquette@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1412749572-29449-1-git-send-email-mturquette@linaro.org> References: <20141008060712.4379.42509@quantum> <1412749572-29449-1-git-send-email-mturquette@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: mturquette@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Move the cpu capacity bits out of arch/arm/ and into the CPUfreq driver. Not all ARM devices will use CPUfreq and it is unsafe to assume as such in topology.c. Instead, use the new capacity_ops introduced into CFS. If this code is generic enough then it could be factored and shared via a header to make it easier for other CPUfreq drivers to take advantage of it. Signed-off-by: Mike Turquette --- This approach simply builds on top of Morten's series. I am not sure that the per-cpu method is the best way to go in the future. And if so I imagine that the CPUfreq core could provide everything except for the cpu_eff part. In general I think that the overlap between CPUfreq drivers and arch/arm/kernel/topology.c is something that needs to addresssed soon, as both pieces of code are re-inventing parts of each other. arch/arm/include/asm/topology.h | 2 ++ arch/arm/kernel/topology.c | 42 ++------------------------------- drivers/cpufreq/arm_big_little.c | 51 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 40 deletions(-) diff --git a/arch/arm/include/asm/topology.h b/arch/arm/include/asm/topology.h index 2fe85ff..3951232 100644 --- a/arch/arm/include/asm/topology.h +++ b/arch/arm/include/asm/topology.h @@ -14,6 +14,8 @@ struct cputopo_arm { }; extern struct cputopo_arm cpu_topology[NR_CPUS]; +extern unsigned long max_raw_capacity; +DECLARE_PER_CPU(unsigned long, cpu_raw_capacity); #define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) #define topology_core_id(cpu) (cpu_topology[cpu].core_id) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 5f049ec..a2c9b5f 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -79,8 +79,8 @@ static unsigned long *__cpu_capacity; static unsigned long middle_capacity = 1; -static unsigned long max_raw_capacity = 1; -static DEFINE_PER_CPU(unsigned long, cpu_raw_capacity); +unsigned long max_raw_capacity = 1; +DEFINE_PER_CPU(unsigned long, cpu_raw_capacity); /* * Iterate all CPUs' descriptor in DT and compute the efficiency @@ -175,44 +175,6 @@ static void update_cpu_capacity(unsigned int cpu) cpu, arch_scale_freq_capacity(NULL, cpu)); } -/* - * Scheduler load-tracking scale-invariance - * - * Provides the scheduler with a scale-invariance correction factor that - * compensates for frequency scaling and micro-architecture differences between - * cpus. - */ - -static DEFINE_PER_CPU(atomic_long_t, cpu_curr_freq); -static DEFINE_PER_CPU(atomic_long_t, cpu_max_freq); - -/* cpufreq callback function setting current cpu frequency */ -void arch_scale_set_curr_freq(int cpu, unsigned long freq) -{ - atomic_long_set(&per_cpu(cpu_curr_freq, cpu), freq); -} - -/* cpufreq callback function setting max cpu frequency */ -void arch_scale_set_max_freq(int cpu, unsigned long freq) -{ - atomic_long_set(&per_cpu(cpu_max_freq, cpu), freq); -} - -unsigned long arch_scale_load_capacity(int cpu) -{ - unsigned long curr = atomic_long_read(&per_cpu(cpu_curr_freq, cpu)); - unsigned long max = atomic_long_read(&per_cpu(cpu_max_freq, cpu)); - unsigned long ret; - - if (!max || !per_cpu(cpu_raw_capacity, cpu)) - return SCHED_CAPACITY_SCALE; - - ret = (curr * SCHED_CAPACITY_SCALE) / max; - ret = (ret * per_cpu(cpu_raw_capacity, cpu)) / max_raw_capacity; - - return ret; -} - #else static inline void parse_dt_topology(void) {} static inline void update_cpu_capacity(unsigned int cpuid) {} diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index a46c223..5baffbd 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -31,7 +31,10 @@ #include #include #include +#include +#include #include +#include #include "arm_big_little.h" @@ -533,9 +536,52 @@ static struct notifier_block bL_switcher_notifier = { .notifier_call = bL_cpufreq_switcher_notifier, }; +/* + * Scheduler load-tracking scale-invariance + * + * Provides the scheduler with a scale-invariance correction factor that + * compensates for frequency scaling and micro-architecture differences between + * cpus. + */ + +static DEFINE_PER_CPU(atomic_long_t, cpu_curr_freq); +static DEFINE_PER_CPU(atomic_long_t, cpu_max_freq); + +/* cpufreq callback function setting current cpu frequency */ +void arch_scale_set_curr_freq(int cpu, unsigned long freq) +{ + atomic_long_set(&per_cpu(cpu_curr_freq, cpu), freq); +} + +/* cpufreq callback function setting max cpu frequency */ +void arch_scale_set_max_freq(int cpu, unsigned long freq) +{ + atomic_long_set(&per_cpu(cpu_max_freq, cpu), freq); +} + +/* + * scale_load_capacity returns the current capacity for a given cpu, adjusted + * for micro-architectural differences and taking into accout cpu frequency + */ +unsigned long scale_load_capacity(int cpu) +{ + unsigned long curr = atomic_long_read(&per_cpu(cpu_curr_freq, cpu)); + unsigned long max = atomic_long_read(&per_cpu(cpu_max_freq, cpu)); + unsigned long ret; + + if (!max || !per_cpu(cpu_raw_capacity, cpu)) + return SCHED_CAPACITY_SCALE; + + ret = (curr * SCHED_CAPACITY_SCALE) / max; + ret = (ret * per_cpu(cpu_raw_capacity, cpu)) / max_raw_capacity; + + return ret; +} + int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) { int ret, i; + unsigned long flags; if (arm_bL_ops) { pr_debug("%s: Already registered: %s, exiting\n", __func__, @@ -550,6 +596,11 @@ int bL_cpufreq_register(struct cpufreq_arm_bL_ops *ops) arm_bL_ops = ops; + spin_lock_irqsave(&cfs_capacity_ops.lock, flags); + cfs_capacity_ops.get_capacity = scale_load_capacity; + spin_unlock_irqrestore(&cfs_capacity_ops.lock, flags); + synchronize_rcu(); + ret = bL_switcher_get_enabled(); set_switching_enabled(ret);