From patchwork Wed Oct 8 06:26:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Turquette X-Patchwork-Id: 38454 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f200.google.com (mail-lb0-f200.google.com [209.85.217.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id AB79F2057C for ; Wed, 8 Oct 2014 06:26:42 +0000 (UTC) Received: by mail-lb0-f200.google.com with SMTP id b6sf4859539lbj.11 for ; Tue, 07 Oct 2014 23:26:41 -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=AcSpCPv1N5foQdfXATbJLSPrEk3QwojBPJEVAakgYsg=; b=N4PlvstTiRPamJt+cw5GTfeHyoEJJuEEjvxlxaxLSwlFUfJ/RN3RysUmwXsr7Nzx3F nxVOVfsIg2a9bZS+Y/pZbPrqGh1rq1RhdD4ZOgaSEcHbSHqQI9gbbcT7JkCkJoj/nDIn wPd89EIsxI7QUV2h7axR22TQ2EVMHWJxt8jtBYbQ1+9SFa7Hz/PVhSLP+ivXlC+pvDGU hKbF/R9Mi0xwA8csJ5KJUPqyLnqzn6KUHAykXCji3M40GKFp2dhVYtAn0TQDBNWqzgp4 J/wadCIjlLo0+KMl6+EKWGcE4RXyTF0ijIAMsS4dFFGnl7HgqKNkMEsZ96VNDSQxwFrz 5dsA== X-Gm-Message-State: ALoCoQnSYXOm5GllhTQEy3t+4Y1eIe2n7DoOPVAyZheu7vHX4VeK/8s21/L6GnjlNrRn/pUznck5 X-Received: by 10.180.221.236 with SMTP id qh12mr4198771wic.4.1412749601477; Tue, 07 Oct 2014 23:26:41 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.170.133 with SMTP id am5ls23493lac.54.gmail; Tue, 07 Oct 2014 23:26:41 -0700 (PDT) X-Received: by 10.152.29.100 with SMTP id j4mr8895490lah.47.1412749601154; Tue, 07 Oct 2014 23:26:41 -0700 (PDT) Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com [209.85.217.182]) by mx.google.com with ESMTPS id ei3si27125861lad.84.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 patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.182 as permitted sender) client-ip=209.85.217.182; Received: by mail-lb0-f182.google.com with SMTP id z11so7277535lbi.41 for ; Tue, 07 Oct 2014 23:26:40 -0700 (PDT) X-Received: by 10.112.164.71 with SMTP id yo7mr8631228lbb.73.1412749600666; Tue, 07 Oct 2014 23:26:40 -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 c5csp9338lbz; Tue, 7 Oct 2014 23:26:39 -0700 (PDT) X-Received: by 10.66.121.168 with SMTP id ll8mr8243769pab.121.1412749599121; Tue, 07 Oct 2014 23:26:39 -0700 (PDT) Received: from mail-pd0-f179.google.com (mail-pd0-f179.google.com [209.85.192.179]) by mx.google.com with ESMTPS id kf2si17336511pad.211.2014.10.07.23.26.38 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 07 Oct 2014 23:26:39 -0700 (PDT) Received-SPF: pass (google.com: domain of mturquette@linaro.org designates 209.85.192.179 as permitted sender) client-ip=209.85.192.179; Received: by mail-pd0-f179.google.com with SMTP id r10so6388731pdi.38 for ; Tue, 07 Oct 2014 23:26:38 -0700 (PDT) X-Received: by 10.68.202.225 with SMTP id kl1mr8150538pbc.21.1412749598353; Tue, 07 Oct 2014 23:26:38 -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.36 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 07 Oct 2014 23:26:37 -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 1/2] sched: cfs: introduce capacity_ops Date: Tue, 7 Oct 2014 23:26:11 -0700 Message-Id: <1412749572-29449-2-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.182 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: , The scheduler needs to know the current capacity of a cpu taking into account micro-architectural differences as well as current cpu frequency. The method for determining this may vary not only from architecture to architecture, but also within differnt platforms of the same architectures. struct capacity_ops allows for a machine-specific backend to provide this data. Access to the ops is protected by rcu_read_lock(). This is to prevent a loadable module that provides capacity_ops callbacks from pulling the rug out from under us while the scheduler is still using the function. A weak arch function used to be responsible for this, but that approach is too limiting. For example various ARM SoCs may have wildly different methods for determining the current cpu capacity. capacity_ops allows many methods to be compiled into the kernel and then selects one at run-time. The default ops require no knowledge of hardware and do nothing. This patch only includes .get_capacity, but future ops for updating and setting the capacity in the works. Signed-off-by: Mike Turquette --- Note that struct capacity_ops should have other members in it in the future. I have an additional patch that I plan to post soon which adds .eval_capacity as a way to for the scheduler to initiate a change in cpu capacity (e.g. scale cpu frequency). include/linux/sched.h | 28 ++++++++++++++++++++++++++++ kernel/sched/fair.c | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index fa0b121..4b69000 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -846,6 +846,34 @@ enum cpu_idle_type { CPU_MAX_IDLE_TYPES }; +/** + * capacity_ops - helpers for understanding and changing scalable cpu capacity + * @get_capacity: returns current capacity of cpu, accounting for + * micro-architecture and frequency variability + * + * capacity_ops contains machine-specific callbacks for retreiving + * power-adjusted capacity and updating capacity on a set of cpus. + * + * The default ops do not interact with hardware. + * + * Using these ops requires holding rcu_read_lock() across the function call to + * protect against function pointers disappearing during use. This can happen + * if a loadable module provides the callbacks and is unloaded during execution + * of the callback. + * + * Updates to the ops (such as implementations based on a CPUfreq backend) + * requires acquring capacity_ops.lock during the change, followed by a call to + * synchronize_rcu(). + */ +struct capacity_ops { + unsigned long (*get_capacity)(int cpu); + spinlock_t lock; +}; + +extern struct capacity_ops cfs_capacity_ops; + +unsigned long default_scale_load_capacity(int cpu); + /* * Increase resolution of cpu_capacity calculations */ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 025bf3c..8124c7b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -2264,8 +2264,6 @@ static u32 __compute_runnable_contrib(u64 n) return contrib + runnable_avg_yN_sum[n]; } -unsigned long arch_scale_load_capacity(int cpu); - /* * We can represent the historical contribution to runnable average as the * coefficients of a geometric series. To do this we sub-divide our runnable @@ -2302,7 +2300,7 @@ static __always_inline int __update_entity_runnable_avg(u64 now, int cpu, u64 delta, periods; u32 runnable_contrib; int delta_w, decayed = 0; - u32 scale_cap = arch_scale_load_capacity(cpu); + u32 scale_cap = cfs_get_capacity(cpu); delta = now - sa->last_runnable_update; /* @@ -5795,14 +5793,44 @@ unsigned long __weak arch_scale_smt_capacity(struct sched_domain *sd, int cpu) return default_scale_smt_capacity(sd, cpu); } -static unsigned long default_scale_load_capacity(int cpu) +unsigned long default_scale_load_capacity(int cpu) { return SCHED_CAPACITY_SCALE; } -unsigned long __weak arch_scale_load_capacity(int cpu) +struct capacity_ops cfs_capacity_ops = { + .get_capacity = default_scale_load_capacity, +}; + +static unsigned long cfs_get_capacity(int cpu) { - return default_scale_load_capacity(cpu); + unsigned long ret; + + rcu_read_lock(); + ret = cfs_capacity_ops.get_capacity(cpu); + rcu_read_unlock(); + + return ret; +} + +/** + * set_default_capacity_ops - reset capacity ops to their default + * @eops - capacity_ops we are reseting + * + * Useful for loadable modules that supply custom capacity_ops callbacks. When + * unloading these modules need to restore the originals before the custom + * callbacks disappear. + * + * FIXME - belongs in kernel/sched/core.c? + */ +void set_default_capacity_ops(struct capacity_ops *eops) +{ + unsigned long flags; + + spin_lock_irqsave(&eops->lock, flags); + eops->get_capacity = default_scale_load_capacity; + spin_unlock_irqrestore(&eops->lock, flags); + synchronize_rcu(); } static unsigned long scale_rt_capacity(int cpu) @@ -8026,6 +8054,7 @@ void print_cfs_stats(struct seq_file *m, int cpu) __init void init_sched_fair_class(void) { #ifdef CONFIG_SMP + spin_lock_init(&cfs_capacity_ops.lock); open_softirq(SCHED_SOFTIRQ, run_rebalance_domains); #ifdef CONFIG_NO_HZ_COMMON