From patchwork Wed May 7 23:23:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 4132541 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 22C0C9F1E1 for ; Wed, 7 May 2014 23:26:29 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0D549201FA for ; Wed, 7 May 2014 23:26:29 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2FC81201C8 for ; Wed, 7 May 2014 23:26:28 +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 1WiBBj-0002St-Fk; Wed, 07 May 2014 23:23:47 +0000 Received: from mail-ob0-f202.google.com ([209.85.214.202]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WiBBh-0002Ps-Iu for linux-arm-kernel@lists.infradead.org; Wed, 07 May 2014 23:23:46 +0000 Received: by mail-ob0-f202.google.com with SMTP id wm4so385921obc.3 for ; Wed, 07 May 2014 16:23:23 -0700 (PDT) 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; bh=Ad1JsmymI+WJD/xPSjuqc4uqB607c+FDkqp2DTkXp6c=; b=TuKouSHIYmVd9qtBhtzv3+HOG/SaU/fCdwgMfw1PYwKzwSPZqYVyX5uNcIktb7REj3 YjPT7nim3DU+xkUPDvliwhnA5qBaEKELgXq4VwhWuAe0HVsZ1MfwMR03WhO1P1eVcDdU VieWoHxDksm82Vf8fMrkIKkzSHDaAPTSSLgoowa35CJe3RPhF1rNUPBOYuAdf74kT7+P ao3ajX+91GbAZjE83AGIM+TSYG2SstJGAnr7XNQBsSlUw9pPhzYsPbnoi11qUjLDMv4I HAHUpeibVHeFoPzmb5EBkuuHqNG23bFxPb418YTbSUSs36HiwmO1MnAe/1Iz5W/2lJIJ MHwg== X-Gm-Message-State: ALoCoQl7r1fE5ilmQwboOtlkqU96lIqvnfoq4oKX7feMCSuNAHwCW6z7p3j6670za823tY8JYKWM X-Received: by 10.43.117.71 with SMTP id fl7mr65526icc.24.1399505002935; Wed, 07 May 2014 16:23:22 -0700 (PDT) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id r64si764106yhh.0.2014.05.07.16.23.22 for (version=TLSv1.1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 07 May 2014 16:23:22 -0700 (PDT) Received: from tictac.mtv.corp.google.com (tictac.mtv.corp.google.com [172.22.72.141]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id 9E75A31C04E; Wed, 7 May 2014 16:23:22 -0700 (PDT) Received: by tictac.mtv.corp.google.com (Postfix, from userid 121310) id 463FD808A7; Wed, 7 May 2014 16:23:22 -0700 (PDT) From: Doug Anderson To: Russell King , Will Deacon Subject: [PATCH] ARM: Don't ever downscale loops_per_jiffy in SMP systems Date: Wed, 7 May 2014 16:23:02 -0700 Message-Id: <1399504982-31181-1-git-send-email-dianders@chromium.org> X-Mailer: git-send-email 1.9.1.423.g4596e3a X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140507_162345_670344_77443EFC X-CRM114-Status: GOOD ( 17.62 ) X-Spam-Score: -1.4 (-) Cc: nicolas.pitre@linaro.org, David Riley , swarren@nvidia.com, marc.zyngier@arm.com, sboyd@codeaurora.org, Doug Anderson , linux-kernel@vger.kernel.org, "Rafael J. Wysocki" , paul.gortmaker@windriver.com, Santosh Shilimkar , olof@lixom.net, John Stultz , Shawn Guo , Sonny Rao , Richard Zhao , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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=-2.5 required=5.0 tests=BAYES_00,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 Downscaling loops_per_jiffy on SMP ARM systems really doesn't work. You could really only do this if: * Each CPU is has independent frequency changes (changing one CPU doesn't affect another). * We change the generic ARM udelay() code to actually look at percpu loops_per_jiffy. I don't know of any ARM CPUs that are totally independent that don't just use a timer-based delay anyway. For those that don't have a timer-based delay, we should be conservative and overestimate loops_per_jiffy. Note that on some systems you might sometimes see (in the extreme case when we're all the way downclocked) a udelay(100) become a udelay(1000) now. Signed-off-by: Doug Anderson --- Note that I don't have an board that has cpufreq enabled upstream so I'm relying on the testing I did on our local kernel-3.8. Hopefully someone out there can test using David's nifty udelay tests. In order to see this you'd need to make sure that you _don't_ have arch timers enabled. See: * https://patchwork.kernel.org/patch/4124721/ * https://patchwork.kernel.org/patch/4124731/ arch/arm/kernel/smp.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 7c4fada..9d944f6 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -649,39 +649,50 @@ int setup_profiling_timer(unsigned int multiplier) #ifdef CONFIG_CPU_FREQ -static DEFINE_PER_CPU(unsigned long, l_p_j_ref); -static DEFINE_PER_CPU(unsigned long, l_p_j_ref_freq); static unsigned long global_l_p_j_ref; static unsigned long global_l_p_j_ref_freq; +static unsigned long global_l_p_j_max_freq; + +/** + * cpufreq_callback - Adjust loops_per_jiffies when frequency changes + * + * When the CPU frequency changes we need to adjust loops_per_jiffies, which + * we assume scales linearly with frequency. + * + * This function is fairly castrated and only ever adjust loops_per_jiffies + * upward. It also doesn't adjust the PER_CPU loops_per_jiffies. Here's why: + * 1. The ARM udelay only ever looks at the global loops_per_jiffy not the + * percpu one. If your CPUs _are not_ changed in lockstep you could run + * into problems by decreasing loops_per_jiffies since one of the other + * processors might still be running slower. + * 2. The ARM udelay reads the loops_per_jiffy at the beginning of its loop and + * no other times. If your CPUs _are_ changed in lockstep you could run + * into a race where one CPU has started its loop with old (slower) + * loops_per_jiffy and then suddenly is running faster. + * + * Anyone who wants a good udelay() should be using a timer-based solution + * anyway. If you don't have a timer solution, you just gotta be conservative. + */ static int cpufreq_callback(struct notifier_block *nb, unsigned long val, void *data) { struct cpufreq_freqs *freq = data; - int cpu = freq->cpu; if (freq->flags & CPUFREQ_CONST_LOOPS) return NOTIFY_OK; - if (!per_cpu(l_p_j_ref, cpu)) { - per_cpu(l_p_j_ref, cpu) = - per_cpu(cpu_data, cpu).loops_per_jiffy; - per_cpu(l_p_j_ref_freq, cpu) = freq->old; - if (!global_l_p_j_ref) { - global_l_p_j_ref = loops_per_jiffy; - global_l_p_j_ref_freq = freq->old; - } + if (!global_l_p_j_ref) { + global_l_p_j_ref = loops_per_jiffy; + global_l_p_j_ref_freq = freq->old; + global_l_p_j_max_freq = freq->old; } - if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || - (val == CPUFREQ_POSTCHANGE && freq->old > freq->new)) { + if (freq->new > global_l_p_j_max_freq) { loops_per_jiffy = cpufreq_scale(global_l_p_j_ref, global_l_p_j_ref_freq, freq->new); - per_cpu(cpu_data, cpu).loops_per_jiffy = - cpufreq_scale(per_cpu(l_p_j_ref, cpu), - per_cpu(l_p_j_ref_freq, cpu), - freq->new); + global_l_p_j_max_freq = freq->new; } return NOTIFY_OK; }